查看原文
其他

微信小程序如何优雅的处理token失效

老猿人 码农闲谈AI 2024-01-22

前言

当我们打开小程序调用完wx.login方法获取到token后,我们就可以在请求header里设置token进去访问后端了.但我们在平时使用token时。肯定是会给token设置一个有效期的。在这样的前提下,如果你没有做一些刷新token的机制且长时间不操作的话。会导致接下来接口请求失效报token异常。那么我们如何在小程序中实现统一的请求接口报token错误时。先去请求一下wx.login接口然后再一次调用需要请求的接口呢?如图:



代码实现
01utils包中新建https.js文件

 

let isRefreshing = true;let subscribers = [];
var  app = getApp();let  baseUrl = app.globalData.baseUrl;function onAccessTokenFetched() {  subscribers.forEach((callback) => {    callback();  })  subscribers = [];}
function addSubscriber(callback) {  subscribers.push(callback)}
export class Http {  constructor() {}req({type, url, data,callback=''}={}) {  let userInfo = wx.getStorageSync('userInfo');  var header={}  if(userInfo){    header = { // 根据需求设置请求头Authorization      'content-type': 'application/json',      "Authorization": userInfo.token,    };  }  let _this = this;  return new Promise((resolve, reject) => { // 返回一个Promise    wx.request({      url: baseUrl + url, // 请求地址      data: data, // 请求参数v      header: header,      method: type,      success: function (res){          if (callback) return callback(res);          if (res.data.code == 404) {            console.log('接口不存在')          } else if (res.data.code == 403) {                        // 将需要重新执行的接口缓存到一个队列中           addSubscriber(() => {             _this.req({ type,url, data, callback: resolve })           })                       if (isRefreshing) {              getNewToken(url, data).then(() => {                // 依次去执行缓存的接口                onAccessTokenFetched();                isRefreshing = true;              })            }            isRefreshing = false;          } else if (res.data.code == 200) {            resolve(res)          } else{            wx.showModal({ content: res.data.msg, showCancel: false });          }      },      fail: function (err ) {        reject(err)      },      enableCache: true,      timeout: 600000, //接口请求超时时间      complete: function (vv) { // 接口调用结束的回调函数(调用成功、失败都会执行)        // console.log(vv);      }    })  }).catch( err => {    console.log(err);  })}
const getNewToken = () => {  return new Promise((resolve, reject) => {    wx.login({      timeout: 5000,      success(res){          wx.request({            url: baseUrl+'/fLogin?code='+res.code,            method: 'GET',            success:(resp)=>{                app.globalData = {                    userInfo: resp.data.userInfo,                    UserLogin: true                }                // 缓存到本地                wx.setStorageSync('userInfo', resp.data.userInfo)                resolve(res)            }          })      }    })  })
}
02utils包中新建api.js文件

 api.js用于统一定义我们的请求后端的接口。你也可以不同模块分别定义接口.

import {Http} from './http'export class Index extends Http {  constructor() {    super();  }    // 获取联系方式列表  getPhoneList(data) {    return this.req({      type: 'GET',      url: '/system/data/fList',      data:data    });  }    setStoreSyncSecond(key, value, time){      wx.setStorageSync(key, value)      var t = time ? time : 24;      var seconds = parseInt(t * 3600);      if (seconds > 0) {        var timestamp = Date.parse(new Date());        timestamp = timestamp / 1000 + seconds;        wx.setStorageSync(key + 'dtime', timestamp + "")      } else {        wx.removeStorageSync(key + 'dtime')      }  }
 getStorageSyncTime(key, def) {      var deadtime = parseInt(wx.getStorageSync(key + 'dtime'))      if (deadtime) {        if (parseInt(deadtime) < Date.parse(new Date()) / 1000) {          wx.removeStorageSync(key);          wx.removeStorageSync(key + 'dtime');          if (def) { return def; } else { return; }        }      }      var res = wx.getStorageSync(key);      if (res) {        return res;      } else if (def) {        return def;      } else {        return;      }    }}03如何控制弹出框或者某个业务多久之内只显示一次

在api.js中我们分别定义了setStoreSyncSecond跟getStorageSyncTime方法。通过这两个方法。我们可以把设置到storeData中的数据保存时间。

具体使用方法:

onLoad(options) {   //获取该key在storeData中的数据,如果没有,则显示弹出框    let show = API.getStorageSyncTime('show_notic',0)    let that = this    if(show ===undefined || show===0){     //显示弹出框后要设置该key多久过期。如1个小时。具体时间可以在方法里控制      API.setStoreSyncSecond('show_notic','1',1)      this.setData({        show:true      })      //弹出宽显示10秒自动关闭      setTimeout(function(){        that.setData({          show:false        })      },10000)    }}

点击关注我吧,发现更多有用分享。让你的技术得到更大提升




END


文中代码参考示例,可点击小程序,进入便民电话本

如需源码学习,可公众号内发送 "工具箱"


继续滑动看下一个

微信小程序如何优雅的处理token失效

老猿人 码农闲谈AI
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存