fix: redirect expired sessions to login
This commit is contained in:
@@ -31,6 +31,17 @@ export function ClientAuthGuard({ isPublicPath, frontendJWT, userInfo }: ClientA
|
||||
return;
|
||||
}
|
||||
|
||||
// 服务端如果已经拿不到有效 session,就不要再信任本地残留 token。
|
||||
// 否则页面会出现“模块全空了”,但又没有跳回登录页的假登录状态。
|
||||
if (!frontendJWT && !userInfo) {
|
||||
console.warn('⚠️ [Auth Guard] 服务端会话已失效,清理本地登录态并跳转登录页');
|
||||
localStorage.removeItem('access_token');
|
||||
localStorage.removeItem('user_info');
|
||||
const redirectTo = `${location.pathname}${location.search}` || '/';
|
||||
navigate(`/login?expired=true&redirect=${encodeURIComponent(redirectTo)}`, { replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
// 优先用服务端 session 回传的数据同步 localStorage。
|
||||
// 不能只在本地没有 token 时才回填,否则本地残留旧 token 会导致:
|
||||
// - SSR 页面可打开(服务端 session 是新的)
|
||||
@@ -55,14 +66,16 @@ export function ClientAuthGuard({ isPublicPath, frontendJWT, userInfo }: ClientA
|
||||
console.log('🔒 [Auth Guard] 未认证,重定向到登录页');
|
||||
|
||||
// 保存当前路径,登录后可以跳转回来
|
||||
const redirectTo = location.pathname !== '/login' ? location.pathname : '/';
|
||||
const redirectTo = location.pathname !== '/login'
|
||||
? `${location.pathname}${location.search}`
|
||||
: '/';
|
||||
|
||||
// 跳转到登录页,并传递重定向目标
|
||||
navigate(`/login?redirect=${encodeURIComponent(redirectTo)}`, { replace: true });
|
||||
} else {
|
||||
// console.log('✅ [Auth Guard] 已认证,允许访问');
|
||||
}
|
||||
}, [isPublicPath, navigate, location.pathname, frontendJWT, userInfo]);
|
||||
}, [isPublicPath, navigate, location.pathname, location.search, frontendJWT, userInfo]);
|
||||
|
||||
// 这个组件不渲染任何内容
|
||||
return null;
|
||||
|
||||
+9
-3
@@ -300,12 +300,18 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
if (error instanceof Error && error.name === 'AuthenticationError') {
|
||||
console.warn("⚠️ [Root Loader] Token 过期,重定向到登录页");
|
||||
// 保存当前路径,登录后可以跳转回来
|
||||
const redirectTo = pathname !== '/login' ? pathname : '/';
|
||||
return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}`);
|
||||
const redirectTo = pathname !== '/login' ? `${pathname}${url.search}` : '/';
|
||||
return redirect(`/login?expired=true&redirect=${encodeURIComponent(redirectTo)}`);
|
||||
}
|
||||
|
||||
console.warn("⚠️ [Root Loader] 获取用户会话失败:", error);
|
||||
// 保持默认值 'common'
|
||||
|
||||
// 非公共页只要服务端会话初始化失败,就直接回登录页,
|
||||
// 避免落入“角色=common + 菜单全空”的假登录状态。
|
||||
if (!isPublicPath) {
|
||||
const redirectTo = pathname !== '/login' ? `${pathname}${url.search}` : '/';
|
||||
return redirect(`/login?expired=true&redirect=${encodeURIComponent(redirectTo)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:认证检查和重定向已在 getUserSession() 中统一处理
|
||||
|
||||
Reference in New Issue
Block a user