React 18 + React Router 6 路由守卫鉴权失效问题排查
路由鉴权失效问题修复
核心问题点
- 守卫判断逻辑完全写反:
ProtectedRoutes(需登录访问的路由组)当前逻辑为「已登录跳转/profile、未登录渲染子路由」,PublicRoutes(未登录可访问的路由组)当前逻辑为「已登录跳转/login」,和需求逻辑完全倒置。 - 路由路径配置不匹配:需求明确未认证可访问
/home,但代码中首页路由仅配置了/路径,未做/home的映射。 - 缺少通配兜底规则:没有配置
*通配路由,无法拦截用户手动输入的非法路径、越权路径,也无法覆盖浏览器后退的边界场景。 - 认证判断为硬编码:当前
isAuthenticated固定返回false,实际使用需要替换为真实登录态读取逻辑(比如从localStorage取token、从全局状态取认证标识)。
修复后代码
RouteGuard.tsx
import { Navigate, Outlet, useLocation } from 'react-router-dom' // 替换为项目真实的认证状态判断逻辑 export const isAuthenticated = () => { // 示例:return !!localStorage.getItem('access_token') return false } // 公共路由守卫:未登录可访问,已登录访问自动跳转到登录后默认页 export const PublicRoutes = () => { const location = useLocation() return !isAuthenticated() ? <Outlet /> : <Navigate to='/profile' state={{ from: location }} replace /> } // 受保护路由守卫:已登录可访问,未登录访问自动跳转到登录页 export const ProtectedRoutes = () => { const location = useLocation() return isAuthenticated() ? <Outlet /> : <Navigate to='/login' state={{ from: location }} replace /> }
Main.tsx
import { Routes, Route, Navigate } from 'react-router-dom' import HomePage from '@modules/home/views' import LoginPage from '@modules/login/views' import ProfilePage from '@modules/profile/views' import SettingsPage from '@modules/Settings/views' import { PublicRoutes, ProtectedRoutes, isAuthenticated } from 'src/middleware/AppRoutes' const AppMain = () => { return ( <main> <Routes> {/* 需登录才可访问的受保护路由组 */} <Route element={<ProtectedRoutes />}> <Route path="/profile" element={<ProfilePage />} /> <Route path="/settings" element={<SettingsPage />} /> </Route> {/* 未登录才可访问的公共路由组 */} <Route element={<PublicRoutes />}> <Route path="/home" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> {/* 根路径根据登录态自动重定向 */} <Route path="/" element={<Navigate to={isAuthenticated() ? '/profile' : '/home'} replace />} /> </Route> {/* 通配兜底:所有不匹配的路径根据登录态跳转至对应有权限的页面 */} <Route path="*" element={<Navigate to={isAuthenticated() ? '/profile' : '/home'} replace />} /> </Routes> </main> ) } export default AppMain
效果验证
- 未登录状态:访问
/profile、/settings会自动跳转至/login,仅可正常访问/home、/login - 已登录状态:访问
/home、/login会自动跳转至/profile,仅可正常访问/profile、/settings - 任意状态下手动修改地址栏输入无权限路径、不存在路径,或点击浏览器后退按钮,都会被守卫拦截,无法进入权限外页面。
内容的提问来源于stack exchange,提问作者PenAndPapers
相关产品推荐
相关产品推荐

