滑动续期与自动刷新:
Web:访问令牌 10 分钟;活跃时自动轮换刷新令牌;连续无操作 30 分钟后清除登录并跳转登录页。 App:会话窗口 3 天;打开 App、恢复前台或请求接口时自动刷新并重新顺延 3 天。 普通登录和 SSO 使用同一策略。 刷新令牌只以 SHA-256 摘要入库,每次刷新都会轮换,旧令牌无法再次使用;退出登录会吊销刷新令牌。 网络临时故障不会误清登录状态,多标签页同时刷新也做了竞争处理。
This commit is contained in:
+34
-5
@@ -1,27 +1,56 @@
|
||||
import axios from 'axios'
|
||||
import { goLogin } from '../utils/navigate'
|
||||
import {
|
||||
authStorageKeys,
|
||||
clearAuthSession,
|
||||
markActivity,
|
||||
refreshAuthSession,
|
||||
refreshIfNeeded,
|
||||
} from '../auth/session'
|
||||
|
||||
const http = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api',
|
||||
timeout: 15000,
|
||||
})
|
||||
|
||||
http.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('jiaowu_token')
|
||||
http.interceptors.request.use(async (config) => {
|
||||
const isAuthenticationRequest =
|
||||
config.url?.endsWith('/auth/login') ||
|
||||
config.url?.endsWith('/auth/refresh') ||
|
||||
config.url?.endsWith('/auth/logout') ||
|
||||
config.url?.endsWith('/auth/sso/exchange') ||
|
||||
config.url?.endsWith('/auth/sso/bind')
|
||||
if (!isAuthenticationRequest) {
|
||||
const activeToken = await refreshIfNeeded(true)
|
||||
if (activeToken) markActivity()
|
||||
}
|
||||
const token = localStorage.getItem(authStorageKeys.token)
|
||||
if (token) config.headers.Authorization = `Bearer ${token}`
|
||||
return config
|
||||
})
|
||||
|
||||
http.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
async (error) => {
|
||||
const isAuthenticationRequest =
|
||||
error.config?.url?.endsWith('/auth/login') ||
|
||||
error.config?.url?.endsWith('/auth/refresh') ||
|
||||
error.config?.url?.endsWith('/auth/logout') ||
|
||||
error.config?.url?.endsWith('/auth/sso/exchange') ||
|
||||
error.config?.url?.endsWith('/auth/sso/bind')
|
||||
const retryableConfig = error.config as
|
||||
(typeof error.config & { _jiaowuRetried?: boolean }) | undefined
|
||||
if (error.response?.status === 401 && !isAuthenticationRequest &&
|
||||
!retryableConfig?._jiaowuRetried) {
|
||||
const token = await refreshAuthSession()
|
||||
if (token && retryableConfig) {
|
||||
retryableConfig._jiaowuRetried = true
|
||||
retryableConfig.headers.Authorization = `Bearer ${token}`
|
||||
return http.request(retryableConfig)
|
||||
}
|
||||
}
|
||||
if (error.response?.status === 401 && !isAuthenticationRequest) {
|
||||
localStorage.removeItem('jiaowu_token')
|
||||
localStorage.removeItem('jiaowu_user')
|
||||
clearAuthSession()
|
||||
goLogin(location.pathname + location.search + location.hash)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
|
||||
Reference in New Issue
Block a user