微信小程序登录过期如何实现用户无感知重连

一、小程序原生能力

微信利用了自己的账号系统,给每个小程序主体提供了拿到该用户在当前主体的唯一识别码(open_id)的api: wx.login

  wx.login({
    success: function (res) {
      if (res.code) {
        callback(null, res.code)
        // 拿到微信给的临时登录凭证code, 用这个code可以去服务器换成open_id
      } else {
        callback('登陆失败!' + res.errMsg)
      }
    }
  })

code换open_id必须通过服务器处理,需要使用到app_secret, 文档地址:
https://developers.weixin.qq.com/miniprogram/dev/api/signature.html

二、一般登录流程

  1. 服务器拿到code之后,去微信服务器换成用户的当前小程序的唯一id: open_id,并生成业务的登录token,然后返回token给前端, 前端通常会将此token缓存在storage里,实现登录状态保持
let login = () => {
  wx.request({
    url: 'login',
    code: code,
    success: (data) => {
      wx.setStorageSync('token', data.token)
    }
  })
}
  1. 前端在请求头里带上token
      wx.request({
        url: requestUrl,
        data: data,
        method: method,
        header: {
          'Authorization': `Bearer ${token}`
        }
      })

三、登录过期重连

当我们认为登录过期时,将未完成的请求加入队列,然后执行登录操作,登录完成之后批量执行队列里的请求

// 用于存储没有complete的请求
const reqQueue = []

// 封装一个通用的请求方法
let Rq = function (param, method, url, callback) {
  let makeRequest = () = > {
    let token = getStorageSync('token', token)
    wx.request({
      url: url,
      data: param,
      method: method,
      header: {
        'Authorization': `${token}`
      },
      complete: function (res) {
        // 发现登录过期
        if (String(res.statusCode) === '401') {
          // 往队列里丢待执行的函数
          reqQueue.push(makeNowRequest)
          login()
          return
        }
        callback(null, res.data)
      }
    })
  }
  makeRequest()
}

修改login函数,登录之后执行队列的函数

let login = () => {
  wx.request({
    url: 'login',
    code: code,
    success: (data) => {
      wx.setStorageSync('token', data.token)
      // 执行队列里的等待函数
     reqQueue.forEach((item) => {
       item()
     })
    }
  })
}

这里最关键的一步就是在401发生的时候,将当时的函数执行上下文存储起来,用于登录重试后的处理。需要明白的是,在微信小程序里是没有cookie的,做数据持久化依赖的是wx.setStorage,以及重试利用回调队列的存储和释放来实现。

你可能感兴趣的:(微信小程序登录过期如何实现用户无感知重连)