feat: 刷新 Access Token(带并发锁)
This commit is contained in:
@@ -95,26 +95,44 @@ export const useAccountStore = defineStore(
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新 Access Token
|
||||
* 刷新 Access Token(带并发锁)
|
||||
*
|
||||
* 由刷新拦截器的 doRefreshToken 调用。
|
||||
* 返回新的 Access Token 字符串,方便拦截器直接使用。
|
||||
* 由刷新拦截器的 doRefreshToken 和 SSE 的 onUnauthorized 调用。
|
||||
* 返回新的 Access Token 字符串,方便调用方直接使用。
|
||||
*
|
||||
* 并发控制:若已有刷新正在进行中,返回同一个 Promise,
|
||||
* 确保无论并发触发多少次,实际只发出一次 /account/refresh 请求。
|
||||
*
|
||||
* @returns 新的 Access Token
|
||||
*/
|
||||
/** 正在进行的刷新 Promise(null 表示无刷新进行中) */
|
||||
let refreshPromise: Promise<string> | null = null
|
||||
|
||||
const refreshAccessToken = async (): Promise<string> => {
|
||||
// 已有刷新进行中 → 复用同一个 Promise,避免并发重复请求
|
||||
if (refreshPromise) {
|
||||
return refreshPromise
|
||||
}
|
||||
|
||||
if (!refreshToken.value) {
|
||||
throw new Error('无 Refresh Token,无法刷新')
|
||||
}
|
||||
|
||||
const res = await refreshApi({ refreshToken: refreshToken.value })
|
||||
accessToken.value = res.data.accessToken
|
||||
if (res.data.refreshToken) {
|
||||
refreshToken.value = res.data.refreshToken
|
||||
}
|
||||
isTokenValid.value = true
|
||||
refreshPromise = (async () => {
|
||||
try {
|
||||
const res = await refreshApi({ refreshToken: refreshToken.value })
|
||||
accessToken.value = res.data.accessToken
|
||||
if (res.data.refreshToken) {
|
||||
refreshToken.value = res.data.refreshToken
|
||||
}
|
||||
isTokenValid.value = true
|
||||
return accessToken.value
|
||||
} finally {
|
||||
refreshPromise = null
|
||||
}
|
||||
})()
|
||||
|
||||
return accessToken.value
|
||||
return refreshPromise
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user