This commit is contained in:
weiwei committed 2025-05-19 15:32:38 +08:00
1 parent 05a2e0f0bb
commit c2a765ebf7
1 file changed
+114 -37
+114 -37
View File
@@ -8,6 +8,28 @@ import showVerifyDeviceImpModel from "../components/verifyDeviceImpModel/verifyD
const TOKEN_KEY = constant.storageConstant.TOKEN
const USER_INFO_KEY = constant.storageConstant.USERINFO
const SKIP_AUTH_URLS = ["/thirdparty/thirdPartyOAth2", "/sys/auth/refresh-token", "/auth/oauth2/token"]
// 是否正在刷新token
let isRefreshing = false
// 定义一个队列,用于存储失败的请求
let failedQueue: any[] = []
// 存储刷新token的Promise
let refreshTokenPromise: Promise<any> | null = null
// 处理队列中的请求
const processQueue = (error: any, token: any = null) => {
failedQueue.forEach((prom) => {
if (error) {
prom.reject(error)
} else {
prom.resolve(token)
}
})
if (!error) {
failedQueue = []
}
}
// 读取token并处理Authorization请求头
const getAuthHeader = (tokenStorage: any) => {
@@ -57,15 +79,15 @@ async function handleShLogin(): Promise<boolean> {
try {
uni.showLoading({ title: "登录中...", mask: true })
const userInfo = await (window as any).CP2.getUserInfo()
if (userInfo.code == 0 || !userInfo.data.accountId || !userInfo.data.sessionId) {
uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
return false
}
// const userInfo = await (window as any).CP2.getUserInfo()
// if (userInfo.code == 0 || !userInfo.data.accountId || !userInfo.data.sessionId) {
// uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
// return false
// }
const { accountId, sessionId } = userInfo.data
const response = await userApi.authsh({ accountId, sessionId })
// const response = await userApi.authsh({ accountId: "67e790d6a95d5a7b507e53dd", sessionId: "68215b03a95d5a4899d20cb4" }) // 测试
// const { accountId, sessionId } = userInfo.data
// const response = await userApi.authsh({ accountId, sessionId })
const response = await userApi.authsh({ accountId: "67e790d6a95d5a7b507e53dd", sessionId: "68215b03a95d5a4899d20cb4" }) // 测试
if (response.code == 0) {
uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken })
@@ -81,14 +103,10 @@ async function handleShLogin(): Promise<boolean> {
return false
}
// if (response.data == -1) {
// uni.showToast({ title: "您的设备需要信任验证", icon: "none" })
// await showVerifyDeviceImpModel(async () => {
// await autoLogin()
// uni.reLaunch({ url: window.location.href.split("#")[1] })
// })
// return false
// }
// 如果是设备未验证,保存响应数据
if (response.data === -1) {
uni.setStorageSync(TOKEN_KEY, { data: -1 })
}
uni.showToast({ title: response.msg || "登录失败", icon: "none" })
return false
@@ -118,6 +136,56 @@ async function autoLogin(): Promise<boolean> {
}
}
// 统一的token刷新函数
async function refreshToken(): Promise<any> {
if (refreshTokenPromise) {
return refreshTokenPromise
}
if (!isRefreshing) {
isRefreshing = true
refreshTokenPromise = (async () => {
try {
const loginResult = await autoLogin()
if (loginResult) {
const newTokenStorage = uni.getStorageSync(TOKEN_KEY)
processQueue(null, newTokenStorage)
return newTokenStorage
} else {
// 检查是否需要设备验证
const tokenStorage = uni.getStorageSync(TOKEN_KEY)
if (tokenStorage?.data === -1) {
// 显示设备验证弹窗
await showVerifyDeviceImpModel(async () => {
// 验证完成后重新登录
const newLoginResult = await autoLogin()
if (newLoginResult) {
const newTokenStorage = uni.getStorageSync(TOKEN_KEY)
processQueue(null, newTokenStorage)
return newTokenStorage
} else {
processQueue(new Error("登录失败"), null)
throw new Error("登录失败")
}
})
} else {
processQueue(new Error("登录失败"), null)
throw new Error("登录失败")
}
}
} catch (error) {
processQueue(error, null)
throw error
} finally {
isRefreshing = false
refreshTokenPromise = null
}
})()
}
return refreshTokenPromise
}
// token过期刷新检查
async function checkAndRefreshToken(tokenStorage: any) {
const { accessToken } = tokenStorage
@@ -125,13 +193,9 @@ async function checkAndRefreshToken(tokenStorage: any) {
const expiresDate = new Date(accessToken.expiresAt).getTime()
// console.log("过期时间", expiresDate)
// console.log("现在时间", new Date().getTime())
// console.log("现在时间大于过期时间吗", new Date().getTime() >= expiresDate)
// token已过期,尝试刷新
if (new Date().getTime() >= expiresDate) {
await autoLogin()
return await refreshToken()
}
}
@@ -166,25 +230,25 @@ http.interceptors.request.use(async (config) => {
config_header["TENANT-ID"] = "1"
if (import.meta.env.VITE_IS_TOC === "true") config_header["CLIENT-TOC"] = "Y"
// 不需要设置认证头的接口路径
const skipAuthUrls = ["/thirdparty/thirdPartyOAth2", "/sys/auth/refresh-token", "/auth/oauth2/token"]
// 判断是否需要设置认证头
if (!skipAuthUrls.some((url) => config.url?.startsWith(url))) {
if (!SKIP_AUTH_URLS.some((url) => config.url?.startsWith(url))) {
if (!isEmpty(tokenStorage)) {
// token存在,token过期刷新检查
await checkAndRefreshToken(tokenStorage)
const authHeader = getAuthHeader(tokenStorage)
if (authHeader) config_header.Authorization = authHeader
const newTokenStorage = await checkAndRefreshToken(tokenStorage)
if (newTokenStorage) {
const authHeader = getAuthHeader(newTokenStorage)
if (authHeader) config_header.Authorization = authHeader
} else {
const authHeader = getAuthHeader(tokenStorage)
if (authHeader) config_header.Authorization = authHeader
}
} else {
// token不存在,则发起登录
await autoLogin()
// 登录后重新获取token
const newTokenStorage = uni.getStorageSync(TOKEN_KEY)
const authHeader = getAuthHeader(newTokenStorage)
if (authHeader) config_header.Authorization = authHeader
// token不存在,使用统一的刷新函数
const newTokenStorage = await refreshToken()
if (newTokenStorage) {
const authHeader = getAuthHeader(newTokenStorage)
if (authHeader) config_header.Authorization = authHeader
}
}
}
@@ -219,7 +283,20 @@ http.interceptors.response.use(
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
router.jump("/pages/test/login")
} else {
await autoLogin()
try {
// 使用统一的刷新函数
const newTokenStorage = await refreshToken()
if (newTokenStorage) {
// 重新发起失败的请求
const config = error.config
const authHeader = getAuthHeader(newTokenStorage)
if (authHeader && config.header) config.header.Authorization = authHeader
return http.request(config)
}
} catch (err) {
// 错误已经在refreshToken中处理
return Promise.reject(err)
}
}
}