这里使用的是自己的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