前端封装统一接口请求函数、token刷新函数,在请求成功之后对返回结果进行校验,如果token过期,则调用token刷新函数请求新的token.\
后端在接收到token刷新请求之后通过结合redis中存放的用户信息、token和refresh_token对请求参数进行验证,验证通过之后生成新的token和refresh_token存放到redis中并返回给前端。至此完成token刷新。
import ajax from '@/uni_modules/u-ajax/js_sdk'
import {
baseURL,
tokenName,
tokenTableName,
requestTimeout,
successCode,
contentType,
invalidCode,
decryptKey
} from '@/config/index.js'
import {
decryptDes
} from '@/utils/encry/des.js'
import store from '@/store/index.js'
const configuration = {
baseURL: baseURL,
timeout: requestTimeout,
header: {
'Content-Type': contentType
}
}
const instance = ajax.create(configuration)
const updateInstance = ajax.create({})
let ajaxData = {}
let refreshLock = false
let obj = {}
let stabilization = true
instance.interceptors.request.use(
config => {
let token = uni.getStorageSync(tokenTableName);
if (
contentType === 'application/x-www-form-urlencoded;charset=UTF-8' &&
config.data
) {
config.data = qs.stringify(config.data)
}
if (token) {
token = JSON.parse(token)
config.header[tokenName] = token.authToken;
}
return config
},
error => {
uni.showToast({
title: response.data.msg,
icon: "none",
duration: 2000
});
return Promise.reject(error)
}
)
instance.interceptors.response.use(
response => {
if (successCode.includes(response.data.code)) {
return response.data
} else {
if (!response.config.url.includes('upms/api/v1/auth/refresh')) {
if (refreshLock) {
return instance(
obj[response.config.url.split(baseURL)[1]]
)
} else {
setTimeout(() => {
refreshLock = false
}, 20)
}
}
}
if (invalidCode.includes(response.data.code) || response.data.code == 401) {
uni.showToast({
title: response.data.msg,
icon: "none",
duration: 2000
});
uni.setStorageSync(tokenTableName, '');
if (stabilization) {
stabilization = false
store.commit("judgeToken", false);
uni.navigateTo({
url: '/pages/login/index'
});
setTimeout(() => {
stabilization = true
}, 5000)
}
} else {
uni.showToast({
title: response.data.msg,
icon: "none",
duration: 2000
});
return Promise.reject(response.data.msg)
}
},
error => {
return Promise.reject(error)
}
)
let subscribers = [];
function onAccessTokenFetched() {
subscribers.forEach((callback) => {
callback();
})
subscribers = [];
}
function addSubscriber(callback) {
subscribers.push(callback)
}
let isRefreshing = true;
function checkStatus(response) {
if (rresponse == null) {
let token = uni.getStorageSync(tokenTableName);
if (token) {
token = JSON.parse(token)
if (isRefreshing) {
refreshTokenRequst()
}
}
isRefreshing = false;
const retryOriginalRequest = new Promise((resolve) => {
addSubscriber(() => {
resolve(request(url, options))
})
});
return retryOriginalRequest;
} else {
return response;
}
}
function refreshTokenRequst() {
let config = {}
config.method = "POST"
config.url = baseURL + '/upms/api/v1/auth/refresh'
let token = uni.getStorageSync(tokenTableName);
token = JSON.parse(token)
config.header = {}
config.header['R-Authorization'] = token.refreshToken;
ajax(config).then((response) => {
console.log(response)
if (successCode.includes(response.data.code)) {
uni.setStorageSync(tokenTableName, decryptDes(response.data.data, decryptKey));
}
isRefreshing = true;
onAccessTokenFetched();
});
}
export default function request(config) {
let token = uni.getStorageSync(tokenTableName) || '';
if (token) {
token = JSON.parse(token)
if (token.expiresAtTs < (new Date().getTime() + 5 * 60 * 1000)) {
if (isRefreshing) {
isRefreshing = false;
refreshTokenRequst()
}
const retryOriginalRequest = new Promise((resolve) => {
addSubscriber(() => {
resolve(instance(config))
})
});
return retryOriginalRequest;
} else {
return instance(config)
}
} else {
return instance(config)
}
}