From 02138147b4fc8562e952dad149ae8e990b6b421e Mon Sep 17 00:00:00 2001 From: loicduong Date: Sat, 7 Sep 2024 15:41:13 +0700 Subject: [PATCH] fix(core): fix refresh token when meet multi requests --- .env | 2 +- src/service/request/index.ts | 24 ++++++++------------ src/service/request/shared.ts | 42 ++++++++++++++++++++++------------- src/service/request/type.ts | 2 +- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/.env b/.env index 1135ce3..c5f4162 100644 --- a/.env +++ b/.env @@ -37,7 +37,7 @@ VITE_SERVICE_LOGOUT_CODES=8888,8889 VITE_SERVICE_MODAL_LOGOUT_CODES=7777,7778 # token expired codes of backend service, when the code is received, it will refresh the token and resend the request -VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998 +VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998,3333 # when the route mode is static, the defined super role VITE_STATIC_SUPER_ROLE=R_SUPER diff --git a/src/service/request/index.ts b/src/service/request/index.ts index 6401a60..900254d 100644 --- a/src/service/request/index.ts +++ b/src/service/request/index.ts @@ -4,7 +4,7 @@ import { getServiceBaseURL } from '@/utils/service' import { localStg } from '@/utils/storage' import { BACKEND_ERROR_CODE, createFlatRequest, createRequest } from '@sa/axios' import type { AxiosResponse } from 'axios' -import { handleRefreshToken, showErrorMsg } from './shared' +import { getAuthorization, handleExpiredRequest, showErrorMsg } from './shared' import type { RequestInstanceState } from './type' const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y' @@ -19,12 +19,8 @@ export const request = createFlatRequest + return instance.request(response.config) as Promise } } diff --git a/src/service/request/shared.ts b/src/service/request/shared.ts index 1048e60..fd3f5fe 100644 --- a/src/service/request/shared.ts +++ b/src/service/request/shared.ts @@ -1,34 +1,44 @@ import { useAuthStore } from '@/store/modules/auth' import { localStg } from '@/utils/storage' -import type { AxiosRequestConfig } from 'axios' import { fetchRefreshToken } from '../api' import type { RequestInstanceState } from './type' -/** - * refresh token - * - * @param axiosConfig - request config when the token is expired - */ -export async function handleRefreshToken(axiosConfig: AxiosRequestConfig) { +export function getAuthorization() { + const token = localStg.get('token') + const Authorization = token ? `Bearer ${token}` : null + + return Authorization +} + +/** refresh token */ +export async function handleRefreshToken() { const { resetStore } = useAuthStore() - const refreshToken = localStg.get('refreshToken') || '' - const { error, data } = await fetchRefreshToken(refreshToken) + const rToken = localStg.get('refreshToken') || '' + const { error, data } = await fetchRefreshToken(rToken) if (!error) { localStg.set('token', data.token) localStg.set('refreshToken', data.refreshToken) + return true + } - const config = { ...axiosConfig } - if (config.headers) { - config.headers.Authorization = data.token - } + resetStore() - return config + return false +} + +export async function handleExpiredRequest(state: RequestInstanceState) { + if (!state.refreshTokenFn) { + state.refreshTokenFn = handleRefreshToken() } - resetStore() + const success = await state.refreshTokenFn + + setTimeout(() => { + state.refreshTokenFn = null + }, 1000) - return null + return success } export function showErrorMsg(state: RequestInstanceState, message: string) { diff --git a/src/service/request/type.ts b/src/service/request/type.ts index 54a2d6b..172a2ca 100644 --- a/src/service/request/type.ts +++ b/src/service/request/type.ts @@ -1,6 +1,6 @@ export interface RequestInstanceState { /** whether the request is refreshing token */ - isRefreshingToken: boolean + refreshTokenFn: Promise | null /** the request error message stack */ errMsgStack: string[] }