Django+微信小程序开发待办清单:完善登录机制

796 views, 2022/01/30 updated   Go to Comments

虽然上一章已经实现了小程序、Django和微信接口服务的链接,但是方式太傻了。傻点如下:

  • 每次小程序启动都会尝试重新获取 Token ,不管现有 Token 是否过期。
  • 如果现有 Token 过期,小程序没有尝试重新静默获取新的 Token 。

不急,本章就来完善整个登录机制。

核心流程

完善登录机制在小程序前端就能搞定,没 Django 什么事儿。

在逻辑层写一个新的方法 isTokenAvailable() ,它会检查缓存中 Token 的获取时间,如果 Token 失效则返回 false ,有效则返回 true

// frontend/pages/index/index.js

Component({
  // ...
  methods: {
    // 返回布尔值,检查token是否过期
    isTokenAvailable() {
      const now = Date.parse(new Date());
      try {
        const accessTime = wx.getStorageSync('access_time')
        if ((accessTime !== '') && (now - accessTime < 5 * 60 * 1000)) {
          return true
        }
      } catch {
        // do something...
      }
      return false
    },
    // ...
  },
})

注意这里获取缓存用的是同步版本 getStorageSync() ,免得执行顺序乱套。前面说过小程序里很多接口都有同步异步两种版本,同步版本通常是在方法名尾部带有 Sync 字样。

考虑到登录逻辑会在很多地方用到,因此将 attached() 函数中原有的登录代码全部挪到一个新方法 getToken() 里,并稍加修改:

// frontend/pages/index/index.js

// ...

methods: {
  // 将 attached 中的代码挪到这个函数中
  // 注意它有一个参数: callback本身是个函数
  getToken(callback) {
    wx.login({
      success(res) {
        if (res.code) {
          wx.request({
            // ...
            success: res => {
              // ...
              // --------------
              // 步骤三:用token获取用户数据
              // --------------
              wx.request({
                ...
                success: res => {
                  // 增加此句
                  // 调用callback
                  // 以便在登录完成后执行后续动作
                  callback()
                }
              })
            }
          })
        } 
        // ...
      }
    })
  },
}

与原代码唯一不同的是,getToken(...) 方法有一个叫 callback 的参数。这个 callback 是个可调用对象(比如函数),并且在步骤三中才执行。它的作用很好理解:登录完之后经常会有些后续流程对吧,比如上传数据、检查缓存之类的,callback 执行的就是这些后续流程。

可能你要问了,传递函数是在搞毛线,在原始调用位置像下面这样顺序写不行吗:

this.getToken();
callback();

答案是不行。因为 wx.login()wx.request() 都是异步的,这样写是没办法保证 callback 一定晚于 wx.login 执行。为了解决此问题,就需要像上面的那样将函数传递进去,确保它在所有网络请求结束后再执行。

行了,准备工作都做好了,接着写个 login() 方法将 isTokenAvailable()getToken() 揉到一起,并在启动时调用:

// frontend/pages/index/index.js

// ...

lifetimes: {
  attached() {
    this.login()
  },
},

methods: {
  // 登录函数
  // 注意它有一个参数: callback本身是个函数
  login(callback = (() => {})) {
    if (!this.isTokenAvailable()) {
      console.log('Get Token from dj.')
      // 获取token并传入callback
      this.getToken(callback)
    } else {
      console.log('Get Token from storage.')
      // 如果缓存中token未过期则直接执行callback
      callback()
    }
  },
  // ...
}
  • login() 方法会在真正需要的时候才刷新 Token ,确保 Token 有效的情况下执行 callback 。
  • callback 默认是个空函数。

多启动几次小程序模拟器,观察下 Token 是否正确从缓存或者 Django 获取到了。

收尾工作

虽然小程序启动时检查了 Token 的有效性,但是万一中途某个时候 Token 失效了呢?保险起见,所有涉及到和 Django 交互的操作,都应该检查 Token 。这包括提交待办清单新条目、清单勾选状态改变两种交互。

由于上面已经打好了基础,改起来就简单了。像这样:

// frontend/pages/index/index.js

// ...

methods: {
  // 重写inputSubmit()函数
  inputSubmit() {
    this.login(() => {
      this._inputSubmit()
    })
  },
  // 将原本的inputSubmit()函数修改为_inputSubmit()
  _inputSubmit() {
    // ...
  },
  // 同样的方法修改checkboxChange()函数
  checkboxChange(e) {
    this.login(() => {
      this._checkboxChange(e)
    })
  },
  // 原checkboxChange修改为_checkboxChange
  _checkboxChange(e) {
    // ...
  }
}

看明白 callback 是哪一块代码了吗?

启动 Django 服务并多尝试几次,现在任何和 Django 有关的操作,都会正确执行登录程序了。

总结

到这里登录功能算是彻底搞定了。

但是还没完啊,搞来搞去这么多章,还没拿到真正的业务数据呢。。

磨刀不误砍柴工,不要慌,最后一章搞定。

点赞 or 吐槽?来博客GitHub评论区!




本文作者: 杜赛
发布时间: 2022年01月30日 - 10:42
最后更新: 2022年01月30日 - 10:42
转载请保留原文链接及作者
本站使用 Github 评论后端。鉴于国内复杂的网络环境,如遇评论无法加载、发表等问题,请尝试刷新页面,或更换上网姿势。