本文介绍如何在 react router v6 中通过自定义路由守卫(如 `privateroute` 和 `anonymousroute`)统一管理双向访问控制——既限制未登录用户访问受保护页面,也阻止已登录用户重复进入登录、注册等无需认证的页面。
在构建现代 React 应用时,仅实现“登录后才能访问 Dashboard”是不够的;同样重要的是防止已登录用户误入 /login、/register 或 /forgotpassword 等无意义甚至存在安全风险的页面。理想方案应保持代码简洁、职责清晰,且不需为每个组件手动添加条件判断。

最佳实践是将认证逻辑拆分为两个语义明确的守卫组件:
二者共享基础鉴权逻辑,但行为互斥,职责分明:
// src/components/routing/PrivateRoute.jsx
import { Outlet, Navigate } from 'react-router-dom';
export function PrivateRoute() {
const user = JSON.parse(localStorage.getItem('user'));
return user ? : ;
}
// src/components/routing/AnonymousRoute.jsx
import { Outlet, Navigate } from 'react-router-dom';
export function AnonymousRoute() {
const user = JSON.parse(localStorage.getItem('user'));
return user ? : ;
}使用方式简洁直观,符合 React Router v6 的嵌套路由设计哲学:
{/* 受保护的路由组:仅登录用户可访问 */} }> } /> } /> {/* 匿名路由组:仅未登录用户可访问 */} {/* 可选:404 页面(放在最后) */} } /> } /> } /> } />
⚠️ 注意事项:localStorage.getItem('user') 仅作示意,生产环境建议使用更健壮的认证状态管理(如结合 JWT 解析、useAuth 自定义 Hook 或 Context + Redux);始终使用 replace: true 避免登录后点击浏览器「返回」按钮重新跳转至登录页;Outlet 是 v6 的关键占位符,必须用于包裹嵌套子路由,不可省略。
若因历史原因必须复用单一组件,可扩展为带配置参数的通用守卫 ProtectedRoute:
function ProtectedRoute({ isAuth = true, target = '/login' }) {
const user = JSON.parse(localStorage.getItem('user'));
if (isAuth) {
return user ? : ;
}
return user ? : ;
}调用时显式声明意图:
}> } /> }> } />
但该方式牺牲了可读性与可维护性,违背单一职责原则,强烈建议优先采用 PrivateRoute + AnonymousRoute 分离方案。
通过这种结构化设计,你不仅能精准控制用户流向,还能为未来扩展角色权限(如 AdminRoute)、多因子验证流程等打下坚实基础。