feat(auth): 防止多次刷新token

This commit is contained in:
liwei 2023-07-13 21:34:34 +08:00
parent 08e0cf5ad5
commit 0eaa327d47

View File

@ -11,6 +11,8 @@ import {
} from '@/utils'; } from '@/utils';
import { handleRefreshToken } from './helpers'; import { handleRefreshToken } from './helpers';
type RefreshRequestQueue = (config: AxiosRequestConfig) => void;
/** /**
* axios请求类 * axios请求类
* @author Soybean<honghuangdc@gmail.com> * @author Soybean<honghuangdc@gmail.com>
@ -20,6 +22,10 @@ export default class CustomAxiosInstance {
backendConfig: Service.BackendResultConfig; backendConfig: Service.BackendResultConfig;
isRefreshing: boolean;
retryQueues: RefreshRequestQueue[];
/** /**
* *
* @param axiosConfig - axios配置 * @param axiosConfig - axios配置
@ -37,6 +43,8 @@ export default class CustomAxiosInstance {
this.backendConfig = backendConfig; this.backendConfig = backendConfig;
this.instance = axios.create(axiosConfig); this.instance = axios.create(axiosConfig);
this.setInterceptor(); this.setInterceptor();
this.isRefreshing = false;
this.retryQueues = [];
} }
/** 设置请求拦截器 */ /** 设置请求拦截器 */
@ -60,7 +68,7 @@ export default class CustomAxiosInstance {
); );
this.instance.interceptors.response.use( this.instance.interceptors.response.use(
(async response => { (async response => {
const { status } = response; const { status, config } = response;
if (status === 200 || status < 300 || status === 304) { if (status === 200 || status < 300 || status === 304) {
const backend = response.data; const backend = response.data;
const { codeKey, dataKey, successCode } = this.backendConfig; const { codeKey, dataKey, successCode } = this.backendConfig;
@ -71,10 +79,24 @@ export default class CustomAxiosInstance {
// token失效, 刷新token // token失效, 刷新token
if (REFRESH_TOKEN_CODE.includes(backend[codeKey])) { if (REFRESH_TOKEN_CODE.includes(backend[codeKey])) {
const config = await handleRefreshToken(response.config); // 原始请求
if (config) { const originRequest = new Promise(resolve => {
return this.instance.request(config); this.retryQueues.push((refreshConfig: AxiosRequestConfig) => {
config.headers.Authorization = refreshConfig.headers?.Authorization;
resolve(this.instance.request(config));
});
});
if (!this.isRefreshing) {
this.isRefreshing = true;
const refreshConfig = await handleRefreshToken(response.config);
if (refreshConfig) {
this.retryQueues.map(cb => cb(refreshConfig));
}
this.retryQueues = [];
this.isRefreshing = false;
} }
return originRequest;
} }
const error = handleBackendError(backend, this.backendConfig); const error = handleBackendError(backend, this.backendConfig);