uniapp-刷新token

33 阅读1分钟

思路

  1. token的作用是一个请求标识,部分接口需要请求头添加token作为身份认证字段;
  2. 后端设定的token有效期是2个小时,过期后接口报错(401),需要更新token才能重新获取数据;

解决思路: 在请求拦截器中判断token是否超时,超时则自动重新获取token

代码

$http.beforeRequest = function(options) {
	uni.showLoading({
		title: '数据加载中...',
	});
	// 超时更新token
	debouncedGetToken()
}
//使用第三方库
import jsrsasign from 'jsrsasign'

// 解析token
export const decodeToken = (token) => {
	let obj = null
	if (token !== '') {
		const payload = jsrsasign.KJUR.jws.JWS.parse(token)
		if (payload.hasOwnProperty('payloadObj')) {
			obj = payload.payloadObj
		}
	}
	return obj
}
// 每个页面都有很多接口,防止一下子重复调用多次
export function debounce(fn, delay = 100) {
	let timer
	return function() {
		const that = this
		const _args = arguments // 存一下传入的参数
		if (timer) {
			clearTimeout(timer)
		}
		timer = setTimeout(function() {
			fn.apply(that, _args)
		}, delay)
	}
}
export async function getToken() {
	// 获取code
	const res = await uni.login().catch(err => err)
	if (res.errMsg !== 'login:ok') {
		return uni.$showMsg('获取code失败!')
	}
	// 获取token;'/api/User/Login'-换成自己的接口, params-调用接口需要的参数
	const {
		data: loginResult
	} = await uni.$http.post('/api/User/Login', params)
	if (loginResult.code !== 200) return uni.$showMsg('更新失败!')
	return loginResult.data.token 
}
export let debouncedGetToken = debounce(async function() {
        // 当前时间
        const timestamp = Date.parse(new Date()) / 1000; 
        // uni.getStorageSync('exp')-第一次登录时存储的‘过期时间’
        if (timestamp > uni.getStorageSync('exp')) {
                try {
                        const token = await getToken({});
                        // vuex中更新token字符串
                        store.commit('m_user/updateToken', token);
                        // 解析token,获取新token的过期时间进行本地存储
                        const decodedToken = decodeToken(token);
                        uni.setStorageSync("exp", decodedToken.exp);
                } catch (error) {
                        console.error("获取token失败", error);
                }
        }
}, 2000); // 设置防抖间隔为2000毫秒(2秒)

补充:(npm下载)

1.接口请求使用的封装网络请求,具体使用:@escook/request-miniprogram - npm (npmjs.com)
2.jsrsasign的使用参考:2022-uni-app解析token标准的方式-使用jsrsasign-爬坑过了_uniapp jsrsasign-CSDN博客