受保护路由与身份验证守卫
使用包装组件或基于加载器的守卫,将未验证身份的用户重定向到登录页。
受保护路由与身份验证守卫 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
为什么要保护路由
某些页面(仪表板、个人资料、管理页面)应该只能由通过身份验证的用户访问。React Router 提供两种方式:包装组件和基于加载器的保护机制。
身份验证状态结构
首先,请建立一个身份验证上下文,让组件可以读取它来判断用户是否已登录。
const AuthContext = React.createContext(null);
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = async (creds) => { const u = await apiLogin(creds); setUser(u); };
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);包装组件保护机制
创建一个 PrivateRoute 组件来检查身份验证状态;如果用户未通过身份验证,则将其重定向到登录页。
import { Navigate, Outlet } from 'react-router-dom';
function PrivateRoute() {
const { user } = useAuth();
if (!user) return <Navigate to="/login" replace />;
return <Outlet />;
}
// Usage in router:
{ element: <PrivateRoute />, children: [
{ path: '/dashboard', element: <Dashboard /> },
]}保留重定向 URL
保存用户尝试访问的 URL,以便登录后将用户送回原页面。通过 Navigate 组件上的 state 传递该 URL。
function PrivateRoute() {
const { user } = useAuth();
const location = useLocation();
if (!user) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return <Outlet />;
}
// In login handler:
const location = useLocation();
const from = location.state?.from?.pathname || '/';
navigate(from, { replace: true });基于加载器的保护机制(数据路由)
在数据路由接口中,向路由的 loader 添加身份验证检查。如果用户未通过身份验证,则抛出重定向。
import { redirect } from 'react-router-dom';
function requireAuth() {
const token = localStorage.getItem('token');
if (!token) throw redirect('/login');
return token;
}
const router = createBrowserRouter([
{
path: '/dashboard',
loader: requireAuth,
element: <Dashboard />,
},
]);基于角色的保护机制
扩展保护机制以检查用户角色。如果用户缺少所需角色,则将其重定向到未授权页面。
function AdminRoute() {
const { user } = useAuth();
if (!user) return <Navigate to="/login" replace />;
if (user.role !== 'admin') return <Navigate to="/unauthorized" replace />;
return <Outlet />;
}身份验证检查期间的加载状态
如果身份验证状态是异步加载的(例如从服务器加载),请在检查处于等待状态时显示加载指示器,以避免登录页短暂闪现。
function PrivateRoute() {
const { user, isLoading } = useAuth();
if (isLoading) return <Spinner />;
if (!user) return <Navigate to="/login" replace />;
return <Outlet />;
}同时保护多个路由
将所有受保护的路由归入一个 PrivateRoute 包装器下,这样就不必在每个路由上单独重复保护机制。
const router = createBrowserRouter([
{ path: '/login', element: <Login /> },
{
element: <PrivateRoute />,
children: [
{ path: '/dashboard', element: <Dashboard /> },
{ path: '/profile', element: <Profile /> },
{ path: '/settings', element: <Settings /> },
],
},
]);处理令牌过期
在保护机制内部或全局拦截器中检查令牌是否过期;令牌过期后退出用户登录,并将其重定向到登录页。
function isTokenValid(token) {
const payload = JSON.parse(atob(token.split('.')[1]));
return payload.exp * 1000 > Date.now();
}
function requireAuth() {
const token = localStorage.getItem('token');
if (!token || !isTokenValid(token)) throw redirect('/login');
return token;
}刷新令牌流程
在因 401 重定向之前,请尝试刷新令牌。只有刷新也失败时,才重定向到登录页。
async function requireAuth() {
let token = localStorage.getItem('token');
if (!token || isExpired(token)) {
token = await refreshToken();
if (!token) throw redirect('/login');
localStorage.setItem('token', token);
}
return token;
}在重新加载后保留身份验证状态
将身份验证令牌存储在 localStorage 或 HttpOnly Cookie 中。应用加载时,请在渲染受保护路由之前恢复身份验证状态。
快速检查
在 React Router 中使用基于加载器的身份验证保护机制时,应抛出什么来重定向未通过身份验证的用户?
回顾
您可以使用带有 <Outlet /> 的 PrivateRoute 包装器,或使用会抛出 redirect() 的加载器来保护路由。在导航状态中保留用户原本要访问的 URL,处理加载状态以避免页面闪现,并将受保护的路由归组以避免重复。
常见问题解答
「受保护路由与身份验证守卫」课时是免费的吗?
是的 — 「受保护路由与身份验证守卫」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「受保护路由与身份验证守卫」这节课中我会学到什么?
使用包装组件或基于加载器的守卫,将未验证身份的用户重定向到登录页。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「受保护路由与身份验证守卫」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 嵌套路由与 Outlet 布局
- 加载器与操作(数据路由 API)
- 受保护路由与身份验证守卫
- 管理 URL 搜索参数中的状态