fix(auth): Extend JWT expiry to 24h + add friendly session expiration UX
Backend: - Extend Access Token expiry from 2h to 24h (long operations like review/deep-research need sufficient time) - Refresh Token remains 7 days Frontend: - Add sessionGuard.ts: centralized session expiration handler with auto token refresh and friendly modal prompt - ASL fetch client: intercept 401, try refresh, retry on success, show friendly modal on failure (was: raw "Unauthorized" red error) - Axios apiClient: replace alert() + bare redirect with friendly session expired modal (covers RVW, IIT, SSA, Admin, DC, PKB) Tested: Token expiration flow verified, friendly modal displays correctly Made-with: Cursor
This commit is contained in:
@@ -15,6 +15,7 @@ import type {
|
||||
ProjectStatistics
|
||||
} from '../types';
|
||||
import { getAccessToken } from '../../../framework/auth/api';
|
||||
import { handleFetchUnauthorized } from '../../../framework/auth/sessionGuard';
|
||||
|
||||
// API基础URL
|
||||
const API_BASE_URL = '/api/v1/asl';
|
||||
@@ -33,10 +34,11 @@ function getAuthHeaders(): HeadersInit {
|
||||
return headers;
|
||||
}
|
||||
|
||||
// 通用请求函数
|
||||
// 通用请求函数(含 401 自动刷新 + 友好提示)
|
||||
async function request<T = any>(
|
||||
url: string,
|
||||
options?: RequestInit
|
||||
options?: RequestInit,
|
||||
_retried = false,
|
||||
): Promise<T> {
|
||||
const response = await fetch(`${API_BASE_URL}${url}`, {
|
||||
...options,
|
||||
@@ -46,14 +48,26 @@ async function request<T = any>(
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status === 401 && !_retried) {
|
||||
let serverMsg = '';
|
||||
try {
|
||||
const body = await response.clone().json();
|
||||
serverMsg = body?.message || '';
|
||||
} catch { /* ignore */ }
|
||||
|
||||
const newToken = await handleFetchUnauthorized(serverMsg);
|
||||
if (newToken) {
|
||||
return request<T>(url, options, true);
|
||||
}
|
||||
throw new Error('登录已过期,请重新登录');
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
// 尝试解析错误响应
|
||||
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
errorMessage = errorData.error || errorData.message || errorMessage;
|
||||
} catch (e) {
|
||||
// 如果响应体不是JSON,使用状态文本
|
||||
const text = await response.text().catch(() => '');
|
||||
if (text) {
|
||||
errorMessage = text;
|
||||
|
||||
Reference in New Issue
Block a user