小程序token过期,刷新token并再次请求失败的请求。

这里使用的是自己的jwt,login后后台会返回给我token和refreshToken。当请求失败时,状态码为401,token无效。然后刷新token,再次请求。

import store from '@/store/index.js'

function loginOut(){
		uni.showToast({
				title: '登录失效,请重新登录',
				icon: 'none'
			})
			setTimeout(()=>{
				uni.clearStorage()
				uni.reLaunch({
					url:'/pages/index/index'
				}) 
			},1500)
}
// 刷新token
async function RefreshTokenRQ(cb){
		try {
				var refreshToken = uni.getStorageSync('RefreshToken')
				if (refreshToken) {
					const refreshTokenStatus = uni.getStorageSync("refreshTokenStatus");
					if (!refreshTokenStatus) {
						uni.setStorageSync('refreshTokenStatus', 'true');s
						console.log(refreshToken,'refreshToken')
						let result = await get(`https://xxxxxx/Login/Refresh?refreshToken=${refreshToken}`)
						console.log(result,'sssss')
						if(result.data.code == 0){
							uni.setStorageSync('MyToken', result.data.tokenResponse.access_token);
							uni.setStorageSync('RefreshToken', result.data.tokenResponse.refresh_token);
							uni.setStorageSync('loginTime', Math.ceil(new Date().getTime()/1000) );
							uni.removeStorageSync('refreshTokenStatus');
							cb && cb()
						} else {
							loginOut()
						}
					}
				} else {
					loginOut()
				}
		} catch (e) {
		}
		console.log("超时了");
}
const request = async(requestObj) => {
	console.log(store.state,'----')
	let headers = [
		{ 'content-type': 'application/json' },
		{ 'content-type': 'application/x-www-form-urlencoded' },
		{ 'content-type': 'application/json', 'Authorization': '' },
	]
	  try {
	    var value = wx.getStorageSync('MyToken')
	    if (value) {
	      headers[2]['Authorization'] = 'Bearer ' + value
	    } else {
			}
	  } catch (e) {
	  }

	return new Promise((resolve, reject) => {
		uni.request({
			// url: baseUrl + url, 
			url: requestObj.url,
			method: requestObj.method || 'GET',
			header: headers[requestObj.header],
			data: requestObj.data || {},
			success: (res) => {
				console.log(store.state.needBeginLogin,'need1')
				let promiseQueue = store.state.promiseQueue;
				if(res.statusCode === 200 ){
					if(requestObj.url.indexOf('/Login') > -1){
						uni.setStorage({
							key:'loginTime',
							data:Math.ceil(new Date().getTime()/1000) 
						}) 
					}
					if (requestObj.resolve){ 
						requestObj.resolve(res);
						let promiseQueueItem = promiseQueue.shift();
						if (store.state.exeQueue){ 
							store.state.exeQueue = false;
							while (promiseQueueItem) {
								request(promiseQueueItem);
								promiseQueueItem = promiseQueue.shift();
								store.state.promiseQueue = promiseQueue;
							}
							if (!promiseQueueItem) {
								store.state.exeQueue = true;
								store.state.needBeginLogin = true;
							}
						}
					}else{
						resolve(res);
					}
				}else if(res.statusCode == 401){
					try{
						var refreshToken = uni.getStorageSync('RefreshToken')
						if(refreshToken){
							requestObj.resolve = resolve;
							promiseQueue.push(requestObj); //请求失败了,把该请求放到promise队列,等待更新token后重新调用。
							console.log(promiseQueue,'promiseQueue')
							console.log(store.state.needBeginLogin,'need2')
							if (!store.state.needBeginLogin) {
								return;
							}
							//防止重复刷新token。
							store.state.needBeginLogin = false;
							RefreshTokenRQ(() => { //获取完token以后执行回调
							//重新登陆以后调用一次队列中的promise;并设置队列为可循环状态。
								let promiseQueueItem = promiseQueue.shift();
								console.log(promiseQueueItem,'promiseQueue')
								if (promiseQueueItem) {
									store.state.exeQueue = true;
									request(promiseQueueItem);
									store.state.promiseQueue = promiseQueue;
								}
							}, true)
						}else {
							loginOut()
						}
					}catch (e){
					}
				} 
			},
			fail: (err) => {
				uni.showToast({
					title: '请求失败',
					icon: 'none'
				})
				reject(err)
			}
		})
	})
}
export function get(url, data, header=2,method = 'GET') {
	return request({url,data,header})
}

export function post(url, data, header=2,method = 'POST') {
	return request({url,data, header,method})
}

export function put(url, data, header=2,method = 'PUT') {
	return request({url, data, header,method})
}

export function del(url, data, header=2,method= 'DELETE') {
	return request({url,data, header,method })
}

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

export default new Vuex.Store({
  state: {
		exeQueue: true,
		promiseQueue: [],
		needBeginLogin:true
	},
  mutations: {},
  actions: {},
  modules: { }
});


参考:https://blog.csdn.net/qq_27223987/article/details/85335680

你可能感兴趣的:(微信小程序)