微信小程序如何处理token过期问题

作者:ArmstrongZ 时间:2023-07-02 05:23:54 

目录
  • 先说结论

  • 问题

  • 解决方案

  • 使用Promise封装回调函数

  • 总结

先说结论

业务流程:  从网络日志中检查到token过期,则跳转到登录页面,要求用户重新登录。

代码逻辑:使用自定义的HttpUtil封装wx.request API,全局捕获过期token并自动处理后,下发给上层业务。

问题

Token过期的现象:

在网络请求中,客户端token会过段时间过期,使得后续的网络请求失败,抛出异常日志如下:


data: {code: "99997", date: 1634174831325, message: "TOKEN EXPIRED", status: "ERROR"}

小程序提供的API: wx.request 是非常简单,只能在请求响应成功后的回调函数中开发者自己去检查token过期,常规的做法:

1.定义检查token过期的方法:


function checkAuth(resp) {
 if(resp.data.code == '99997') { //我们服务器返回的token过期的code是99997,code可以和后台自定义。
   wx.navigateTo({
     url: '/pages/login/login', //这里跳转到登录页,要求用户重新登录
   })
   console.log("需要重新登录......");
 }
}

2.在每个请求接口的响应中,调用checkAuth(res)去捕获token过期。

问题代码


function createMatchImage(data, fun) {
 //console.log(getApp())
 console.log("token = " + getApp().getToken())
 wx.request({
   method: 'POST',
   url: conf.baseUrl + 'match/matchImages',
   data: data,
   header: {
     'content-type': 'application/json',
     'sessionKey': getApp().getToken()
   },
   success: function (res) {
     console.log(res)
     conf.checkAuth(res) // 判断token是否过期,如果过期则跳转到登录页。
     fun(res);
   }
 });
}

function getMatchImages(id, fun) {
 wx.request({
  ...
   success: function (res) {
     conf.checkAuth(res)
  ...
   }
 });
}

function deleteImage(id, fun) {
...
 wx.request({
   ...
   success: function (res) {
     conf.checkAuth(res)
     fun(res);
     //return res;
   }
 });
}

在上面的代码中,每个接口都会有重复的代码,如配置baseUrl,token,checkAuth()。所以这里我们可以进一步去除重复代码。

解决方案

统一网络请求的入口,定义HttpUtil类。  封装wx.request方法。


const get = (url, success, fail) => {
   var _token = getApp().getToken()
   wx.request({
     method:'GET',
     url: baseUrl + url,
     header:{
       'Authorization': _token,
       'content-type': 'application/json',
     },
     success:function(res) {
       checkAuth(res) // 在此处统一拦截token过期,跳转到登录界面
       console.log(res)
       success(res)
     },
     fail:function(res){
       console.log("请求失败")
       fail(res)
     }
   })
}
···

module.exports = {
   get: get,
   post: post
}

HttpUtil的使用场景:


const httpUtil= require("../common/http/HttpUtil")

//逻辑层发起网络请求,只需要传递url和成功回调函数。这比以前更加简洁。
function getActivities(success) {
   httpUtil.get('meetup/api/v1/activity/getActivityList?pageNo=1&pageSize=100', function(res) {
       success(res)
   })
}

module.exports = {
   getActivities : getActivities
}

如上,在使用httpUtil时, 处理token过期的过程是透明的 ,细节封装到了内部。同时业务方也省去了设置token,token过期处理,baseUrl等样板代码。

使用Promise封装回调函数

我们可以使用Promise,省去在调用请求接口时,传入回调函数。


const get = (params) => {
   var _token = getApp().getToken()
   return new Promise((resolve, reject) => {
     wx.request({
       method:'GET',
       url: concatUrl(params),
       header:{
         'Authorization': _token,
         'content-type': 'application/json',
       },
       success: (res) => {
         checkAuth(res) // 在此处统一拦截token过期,跳转到登录界面
         resolve(res)
       },
       fail:(err) => {
         console.log("请求失败")
         reject(err)
       }
     })
   })
}

使用方法:


// service层,定义网络接口
function getActivities() {
   return HttpUtil.get({
       url: 'meetup/api/v1/activity/getActivityList?pageNo=1&pageSize=100'
   })
}
   /**
    * 加载活动列表(其中先加载群组以得到活动的头像)
    */
   fetchGroupAndActivities: function(){
     if(this.data.isLogin) {
       var that = this
       getGroups() //先加载群组列表的头像。
       .then((res)=>{
         if(res.data.code == "10000") {
           ...
           return getActivities()  //其次,加载活动列表
         }
       })
       .then((res)=>{ //链式调用,处理活动列表数据。
         if (res.data.code == "10000") {
         ...
         }
       })
       .catch((err) => { //统一捕获异常。 上面then中的任意回调发送异常,会直接中断调用链,在这里处理。
         console.log("get act and group failed...")
       })
   }},

总结

封装过程wx.requestAPI中,在HttpUtil内部用Promise对象封 * aseUrl,token处理等,隐藏实现细节,对外提供统一接口和支持链式调用,这是常见的门面设计模式,缺点是违背了开闭原则,如果新增一些拦截请求接口处理,则要修改原有的接口实现。后续可加一个中间层,作为 * ,用于扩展新功能。

来源:https://blog.csdn.net/zengqiang11111/article/details/120758488

标签:小程序,token,过期
0
投稿

猜你喜欢

  • python 使用第三方库requests-toolbelt 上传文件流的示例

    2021-05-13 05:48:31
  • js实现三张图(文)片一起切换的banner焦点图

    2024-06-20 04:17:16
  • MySQL实现JDBC详细步骤

    2024-01-28 13:39:11
  • 图解Python中浅拷贝copy()和深拷贝deepcopy()的区别

    2021-12-09 21:09:39
  • php字符串函数 str类常见用法示例

    2024-05-11 10:01:43
  • MySQL图形化管理工具Navicat安装步骤

    2024-01-29 05:00:45
  • MySQL 开启慢查询日志的方法

    2024-01-20 13:41:05
  • sql not in 与not exists使用中的细微差别

    2024-01-26 09:40:43
  • Python约瑟夫生者死者小游戏实例讲解

    2023-02-12 02:14:25
  • phpword插件导出word文件时中文乱码问题处理方案

    2024-05-13 09:24:03
  • python脚本之一键移动自定格式文件方法实例

    2021-08-13 09:41:55
  • Bootstrap每天必学之响应式导航、轮播图

    2023-08-15 03:29:45
  • JavaScript 禁止用户保存图片的实现代码

    2024-04-28 09:48:11
  • 关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)

    2024-01-13 20:06:12
  • 解决Shell执行python文件,传参空格引起的问题

    2021-08-22 10:05:25
  • 十个Python中常用的pip命令总结

    2022-04-05 02:31:16
  • 网页视频播放器程序代码(通用代码),支持avi,wmv,asf,mov,rm,ra,ram等

    2008-07-16 11:56:00
  • Python读取一个目录下所有目录和文件的方法

    2023-05-30 23:04:21
  • Python中enumerate函数代码解析

    2023-05-01 09:13:52
  • 如何在Django中设置定时任务的方法示例

    2023-03-21 06:19:07
  • asp之家 网络编程 m.aspxhome.com