但使书种多,会有岁稔时。这篇文章主要讲述uni-app 无痛刷新 token 方法相关的知识,希望能为你提供帮助。
为了给用户一个流畅的体验, token 过期后需要重新请求新的 token 替换过期的 token
前端在请求接口时,和后端定义好了,如果状态码为 401 ,则表明 token 过期,需要前端请求新的 token
流程思路参考:
https://www.jianshu.com/p/58f05bf13b7d
大概流程如下:
1.用户登录之后,后端会返回两个 token ,分别为
accessToken 和
refreshToken 存储到
Storage
平时请求数据时,请求头使用
accessToken 来发送接口
2.当返回401 token 过期后, 我们通过接口向后端获取新的 token ,请求参数为
refreshToken
3.我们拿到新的
accessToken 和
refreshToken 之后, 替换掉之前的
Storage 中存储的 token
【uni-app 无痛刷新 token 方法】4.同时还要将我们报 401 的哪个接口 ,使用新的
accessToken ,重新请求一次, 拿到数据,实现无痛刷新 token
5.如果后端返回的新的 token 也无法使用,表明需要重新登录,跳到登录页(这一步可以灵活使用,我个人用的是一个路由插件配合使用的: https://ext.dcloud.net.cn/plugin?id=578)
配合uni-app的插件进行使用和实现:
到uni-app的插件市场下载
封装的request网络请求
,按照文档配置到自己的项目上
地址:
https://ext.dcloud.net.cn/plugin?id=159
配置好后修改
vmeitime-http 文件夹下的
index.js 文件
文章图片
文章图片
再修改 vmeitime-http 文件夹下的 interface.js 文件,将401状态暴漏出来
文章图片
如果看到这里还是看不明白,那么请看我的源码,请注意我使用了两个插件,观众们酌情理解,仔细消化,配合到自己的项目中思考...
源码点下面的折叠小加号 ? (老有人问我要源码,源码在下面)
文章图片
文章图片
import http from \'./interface\' import config from \'./config\'// request.js import Vue from \'vue\' import Routerfrom \'@/router\'//...其它逻辑代码export const execute = (name, data = https://www.songbingjia.com/android/{}) => {//设置请求前拦截器 http.interceptor.request = (config) => { let token = uni.getStorageSync(/'accessToken\') delete config.header[\'x-access-token\'] if (token) { config.header[\'x-access-token\'] = token } } //设置请求结束后拦截器 http.interceptor.response = async (response) => { const statusCode = response.statusCode; if (statusCode === 401) { response = await doRequest(response) } if (statusCode === 402) { uni.removeStorageSync(\'accessToken\'); uni.removeStorageSync(\'refreshToken\'); uni.removeStorageSync(\'realname\'); let jump = uni.getStorageSync(\'jump\') if (!jump) { setTimeout(() => { uni.showModal({ title: \'提示\', content: \'您的账号在其它地点登录!\', showCancel: false, success: function(res) { if (res.confirm) { Router.push({ name: \'login\', params: { \'RouterName\': \'home\' } }) } }, }) }); uni.setStorageSync(\'jump\', \'true\') } } if (statusCode == 403) { let jump = uni.getStorageSync(\'jump\') if (!jump) { setTimeout(() => { Router.replace({ name: \'login\', params: { \'RouterName\': \'home\' } }) },500) uni.setStorageSync(\'jump\', \'true\') } } // 统一处理错误请求 const code = response.data.code; const message = response.data.message; if (response.statusCode == 200 & & code !== 0 & & code != -1 & & code) { uni.showToast({ title: message, icon: "none", duration: 2000 }); } return response; } return http.request({ name: name, baseUrl: config.base, url: config.interface[name].path, method: config.interface[name].method ? config.interface[name].method : \'GET\', dataType: \'json\', data, }) }export default { execute } // 刷新 token 方法 async function doRequest(response) { const res = await execute(\'refresh\', {refreshToken: uni.getStorageSync(\'refreshToken\')}) const { code, data } = res.data if (code == 0) { uni.setStorageSync(\'accessToken\', data.accessToken) uni.setStorageSync(\'refreshToken\', data.refreshToken) let config = response.config config.header[\'x-access-token\'] = data.accessToken const resold = await execute(config.name,{ ...config.data }) return resold } else { uni.removeStorageSync(\'accessToken\'); uni.removeStorageSync(\'refreshToken\'); uni.showToast({ title: \'登陆过期请重新登陆!\', icon: "none", success() { Router.push({ name: \'login\', params: { \'RouterName\': \'home\' } }) } }); } }
View Code
推荐阅读
- Android WebServer相关项目
- Android面向切面编程(AOP)(转)
- Appium中app的元素定位
- exposed beyond app through ClipData.Item.getUri()
- 权威盲盒幸运盒子app软件开发
- Appium遇到的坑环境配置无误,路径无中文,无空格,提示error: Logcat capture failed: spawn ENOENT
- 转(applicationContext.xml文件放置位置不同而导致的jUnit测试的时候路径的不同)
- CSAPP_AttackLab实验报告
- 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制