RequireAuth.tsx
1.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// REQ-USR-004: 受保护路由守卫(BR1)。三态:unauthenticated / authResolving / ready。
import { Navigate, Outlet, useLocation } from 'react-router-dom';
import { Spin } from 'antd';
import { useAppSelector } from '../store/hooks';
/**
* 布局守卫:
* - 无 token → 重定向 /login,携带 state.from(来源路径,登录后可回跳,BR1)
* - 有 token 但 user 未就绪 → 渲染 Spin 占位(authResolving,token 已存在但用户信息尚未拉取)
* - token + user 均就绪 → 放行(ready),渲染 <Outlet/>
*/
export default function RequireAuth() {
const { token, user } = useAppSelector((s) => s.auth);
const location = useLocation();
if (!token) {
return <Navigate to="/login" replace state={{ from: location.pathname }} />;
}
if (!user) {
return (
<div
data-testid="auth-resolving"
style={{
height: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Spin size="large" tip="加载中…">
<div style={{ padding: 24 }} />
</Spin>
</div>
);
}
return <Outlet />;
}