uniapp token 自刷新

478 阅读1分钟

笔记 一、获取access_token/refresh_token调试接口 (yuque.com)

SpringCloud微服务实战——搭建企业级开发框架(二十三):Gateway+OAuth2+JWT实现微服务统一认证授权 - 简书 (jianshu.com)

实现无感刷新token,我是这样做的 - 掘金 (juejin.cn)

思路借鉴如上

后端的话就是给一个 token,一个 refreshToken 前者过期的时间要小于后者的过期时间。 登陆的时候传client ID

	async oauthToken ({ commit }, data) {
			data.grant_type = "app_captcha";
			const res = await ajax.post(api.oauthToken, data, {
				header: {
					'Content-Type': 'application/x-www-form-urlencoded',
					'clientId': config.VUE_APP_CLIENT_SECRET
				},
				authorization: 'Basic Z2l0ZWdnLWFkbWluOjEyMzQ1Ng=='
			});
			uni.setStorageSync('token', res.data.token);
			console.log('res.data.token???????????????????', res.data.token,);
			uni.setStorageSync('refTokerefreshTokenn', res.data.refreshToken);
			console.log('res.data.refreshTokenres::::::::::::::', res.data.refreshToken);

			return res;
		},

image.png

在request.js的相应拦截里面 和后端商量token 过期的code 这里是 401

import ajax from '../uni_modules/u-ajax/js_sdk/index.js';
import cg from './config.js';
const instance = ajax.create({
	// 初始化配置
	baseURL: cg.url
});
const authorization = 'Bearer ' + (uni.getStorageSync('token') ? uni.getStorageSync('token') : '');

//添加请求拦截器
instance.interceptors.request.use(
	config => {
		if (config.url.indexOf('/oauth/token') === -1) {
			config.header.authorization = 'Bearer ' + (uni.getStorageSync('token') ? uni.getStorageSync('token') : '');
		} else {
			config.header.authorization = 'Basic Z2l0ZWdnLWFkbWluOjEyMzQ1Ng==';
		}
		if (config.url.indexOf('/oauth/captcha') >= 0 || config.url.indexOf('captcha/send') >= 0 || config.url.indexOf('/code/check') >= 0) {
			config.header.authorization = 'Basic Z2l0ZWdnLWFkbWluOjEyMzQ1Ng==';
		}
		return config;
	},
	error => {
		return Promise.reject(error);
	}
);
// 是否正在刷新的标记
let isRefreshing = false
//重试队列
let requests = []
instance.interceptors.response.use(
	response => {
		//约定code 401 token 过期
		if (response.data.code === 401) {
			if (!isRefreshing) {
				isRefreshing = true
				//调用刷新token的接口
				return this.$store.dispatch(oauthToken, { refreshToken: uni.getStorageSync('refreshToken'), token: uni.getStorageSync('token') })
					.then(res => {
						const { token } = res.data
						// 替换token
						uni.setStorageSync('token', token);
						response.headers.Authorization = `${token}`
						// token 刷新后将数组的方法重新执行
						requests.forEach((cb) => cb(token))
						requests = [] // 重新请求完清空
						return instance(response.config)
					}).catch(err => {
						//跳到登录页
						//清除token
						uni.removeStorageSync('token')
						uni.showToast({
							title: '登陆过期请重新登陆!',
							icon: 'error',
							duration: 1500,
							complete () {
							}
						});
						setTimeout(() => {
							uni.navigateTo({
								url: '/pages/login/login'
							});
						}, 1500)
						return Promise.reject(err)
					}).finally(() => {
						isRefreshing = false
					})
			} else {
				// 返回未执行 resolve 的 Promise
				return new Promise(resolve => {
					// 用函数形式将 resolve 存入,等待刷新后再执行
					requests.push(token => {
						response.headers.Authorization = `${token}`
						resolve(instance(response.config))
					})
				})
			}
		}
		return response && response.data
	},
	(error) => {
		console.log(error.response.data.msg)
		return Promise.reject(error)
	}
)


export default instance;

config.js

export default {
	url: 'https://test.zzyykjyxgs.com/api',
	// url: 'http://192.168.2.247:8080',
	authorization: 'Bearer ' + (uni.getStorageSync('token') ? uni.getStorageSync('token') : ''),
	tenantId: 0,
	"VUE_APP_CLIENT_SECRET": 'Y3VzdG9tZXItYXBwOkFBQWFhYTExMQ=='
}