React 本身没有像 Vue (beforeEach) 那样内置的路由守卫一般都是通过React Router 登录状态 权限控制 高阶组件(HOC) / 自定义组件 / Hook来实现。React 企业项目后台管理、ERP、OA、CMS一般都会实现四层权限登录认证(Auth) ↓ 路由权限(Route Guard) ↓ 菜单权限(Menu Permission) ↓ 按钮权限(Button Permission)下面按照企业项目的方式完整讲解。一、React 路由守卫是什么作用用户访问页面之前先判断有没有权限。例如未登录 访问 /login √ /home × 跳到 login /user × /system ×登录以后admin /home √ /system √ /user √普通用户/home √ /system × /user √所以路由守卫主要干三件事① 是否登录 ② 是否有角色权限 ③ 是否有页面权限二、React Router v6 路由例如import { BrowserRouter, Routes, Route } from react-router-dom; BrowserRouter Routes Route path/login element{Login /} / Route path/ element{Layout /} Route pathhome element{Home /} / Route pathuser element{User /} / Route pathsystem element{System /} / /Route /Routes /BrowserRouter但是这里任何人都能访问。需要加守卫。三、第一层登录守卫创建AuthRoute.tsximport { Navigate } from react-router-dom; export default function AuthRoute({ children }) { const token localStorage.getItem(token); if (!token) { return Navigate to/login replace /; } return children; }然后包裹页面。Route path/ element{ AuthRoute Layout / /AuthRoute } /流程访问 ↓ 有没有token ↓ 没有 ↓ Navigate(/login) ↓ 有 ↓ 继续访问四、token 一般存哪里企业里一般登录 ↓ 接口返回 { token:xxxxx }保存localStorage.setItem(token, token);退出登录localStorage.removeItem(token);或者Reduxstore.user.token或者ContextUserContext五、第二层角色权限后台一般返回{ username:admin, role:admin }或者{ roles:[ admin, editor ] }定义路由const routes [ { path:/home, element:Home/ }, { path:/system, roles:[admin], element:System/ }, { path:/user, roles:[admin,editor], element:User/ } ]守卫const role editor; if(route.roles){ if(!route.roles.includes(role)){ return Navigate to/403/ } }效果admin home √ system √ user √editor home √ system × user √六、第三层菜单权限后台返回[ /home, /user ]说明用户只能看到首页 用户管理菜单配置const menus [ { path:/home, title:首页 }, { path:/user, title:用户 }, { path:/system, title:系统设置 } ]过滤const permission [/home,/user]; const menu menus.filter(item{ return permission.includes(item.path); })最终首页 用户管理系统设置不会显示。七、第四层按钮权限后台返回[ user:add, user:delete, user:update ]页面button新增/button button删除/button button修改/button可以封装function Permission({ code, children }) { const buttons [ user:add, user:update ]; if(buttons.includes(code)){ return children; } return null; }使用Permission codeuser:add Button新增/Button /Permission Permission codeuser:delete Button删除/Button /Permission结果新增 √ 删除 ×八、动态路由权限企业最常见很多后台不会把所有路由写死。登录后login ↓ token ↓ 获取用户信息 ↓ 获取权限 ↓ 后台返回路由 ↓ 动态生成React Router例如后台返回[ { path:/home, component:Home }, { path:/user, component:User } ]前端映射const componentMap { Home: Home, User: User, System: System }; const routes backendRoutes.map(item ({ path: item.path, element: React.createElement(componentMap[item.component]) }));这样后台控制哪些页面能访问不用重新发版。九、完整流程企业项目用户访问 ↓ Route Guard ↓ 有没有token ↓ 没有 ↓ login ↓ 登录 ↓ token ↓ 获取用户信息 ↓ 获取角色 ↓ 获取菜单权限 ↓ 获取按钮权限 ↓ 动态生成菜单 ↓ 动态生成路由 ↓ 进入首页十、推荐项目目录结构src │ ├── router │ ├── index.tsx // 路由入口 │ ├── routes.ts // 路由配置 │ ├── AuthRoute.tsx // 登录守卫 │ ├── PermissionRoute.tsx// 权限守卫 │ ├── layouts │ └── Layout.tsx │ ├── pages │ ├── Login │ ├── Home │ ├── User │ └── System │ ├── store │ └── user.ts // token、角色、权限 │ ├── hooks │ └── usePermission.ts // 权限 Hook │ ├── components │ └── Permission.tsx // 按钮权限组件 │ └── utils └── auth.ts // token 工具十一、企业级最佳实践React Router v6 Redux对于使用React Router v6 Redux或 Zustand的中大型项目推荐采用以下职责划分模块职责数据来源登录认证校验 Token 是否存在、是否过期localStorage Redux路由守卫拦截未登录用户、校验页面访问权限Redux 中的用户信息和权限菜单权限根据后端返回的菜单列表动态渲染侧边栏后端菜单接口动态路由根据后端返回的路由配置生成可访问路由路由配置接口按钮权限控制按钮、操作入口是否显示或禁用后端权限码如user:add权限 Hook封装权限判断逻辑如usePermissionRedux/ZustandPermission组件在 JSX 中优雅地控制权限显示权限 Hook这种分层方式具有以下优点职责清晰认证、路由、菜单、按钮权限互不耦合。便于扩展新增角色或权限类型时只需调整权限配置和判断逻辑。符合企业后台实践适用于 React Ant Design、React Material UI 等常见后台管理系统也便于与 RBAC基于角色的访问控制模型结合。支持动态权限能够结合后端返回的数据实现菜单、路由和按钮权限的统一管理。如果你正在准备前端面试这套实现登录认证 路由守卫 动态路由 菜单权限 按钮权限 RBAC基本覆盖了 React 中后台项目关于权限控制的高频考点。
react路由守卫、权限控制实现
发布时间:2026/6/29 17:39:54
React 本身没有像 Vue (beforeEach) 那样内置的路由守卫一般都是通过React Router 登录状态 权限控制 高阶组件(HOC) / 自定义组件 / Hook来实现。React 企业项目后台管理、ERP、OA、CMS一般都会实现四层权限登录认证(Auth) ↓ 路由权限(Route Guard) ↓ 菜单权限(Menu Permission) ↓ 按钮权限(Button Permission)下面按照企业项目的方式完整讲解。一、React 路由守卫是什么作用用户访问页面之前先判断有没有权限。例如未登录 访问 /login √ /home × 跳到 login /user × /system ×登录以后admin /home √ /system √ /user √普通用户/home √ /system × /user √所以路由守卫主要干三件事① 是否登录 ② 是否有角色权限 ③ 是否有页面权限二、React Router v6 路由例如import { BrowserRouter, Routes, Route } from react-router-dom; BrowserRouter Routes Route path/login element{Login /} / Route path/ element{Layout /} Route pathhome element{Home /} / Route pathuser element{User /} / Route pathsystem element{System /} / /Route /Routes /BrowserRouter但是这里任何人都能访问。需要加守卫。三、第一层登录守卫创建AuthRoute.tsximport { Navigate } from react-router-dom; export default function AuthRoute({ children }) { const token localStorage.getItem(token); if (!token) { return Navigate to/login replace /; } return children; }然后包裹页面。Route path/ element{ AuthRoute Layout / /AuthRoute } /流程访问 ↓ 有没有token ↓ 没有 ↓ Navigate(/login) ↓ 有 ↓ 继续访问四、token 一般存哪里企业里一般登录 ↓ 接口返回 { token:xxxxx }保存localStorage.setItem(token, token);退出登录localStorage.removeItem(token);或者Reduxstore.user.token或者ContextUserContext五、第二层角色权限后台一般返回{ username:admin, role:admin }或者{ roles:[ admin, editor ] }定义路由const routes [ { path:/home, element:Home/ }, { path:/system, roles:[admin], element:System/ }, { path:/user, roles:[admin,editor], element:User/ } ]守卫const role editor; if(route.roles){ if(!route.roles.includes(role)){ return Navigate to/403/ } }效果admin home √ system √ user √editor home √ system × user √六、第三层菜单权限后台返回[ /home, /user ]说明用户只能看到首页 用户管理菜单配置const menus [ { path:/home, title:首页 }, { path:/user, title:用户 }, { path:/system, title:系统设置 } ]过滤const permission [/home,/user]; const menu menus.filter(item{ return permission.includes(item.path); })最终首页 用户管理系统设置不会显示。七、第四层按钮权限后台返回[ user:add, user:delete, user:update ]页面button新增/button button删除/button button修改/button可以封装function Permission({ code, children }) { const buttons [ user:add, user:update ]; if(buttons.includes(code)){ return children; } return null; }使用Permission codeuser:add Button新增/Button /Permission Permission codeuser:delete Button删除/Button /Permission结果新增 √ 删除 ×八、动态路由权限企业最常见很多后台不会把所有路由写死。登录后login ↓ token ↓ 获取用户信息 ↓ 获取权限 ↓ 后台返回路由 ↓ 动态生成React Router例如后台返回[ { path:/home, component:Home }, { path:/user, component:User } ]前端映射const componentMap { Home: Home, User: User, System: System }; const routes backendRoutes.map(item ({ path: item.path, element: React.createElement(componentMap[item.component]) }));这样后台控制哪些页面能访问不用重新发版。九、完整流程企业项目用户访问 ↓ Route Guard ↓ 有没有token ↓ 没有 ↓ login ↓ 登录 ↓ token ↓ 获取用户信息 ↓ 获取角色 ↓ 获取菜单权限 ↓ 获取按钮权限 ↓ 动态生成菜单 ↓ 动态生成路由 ↓ 进入首页十、推荐项目目录结构src │ ├── router │ ├── index.tsx // 路由入口 │ ├── routes.ts // 路由配置 │ ├── AuthRoute.tsx // 登录守卫 │ ├── PermissionRoute.tsx// 权限守卫 │ ├── layouts │ └── Layout.tsx │ ├── pages │ ├── Login │ ├── Home │ ├── User │ └── System │ ├── store │ └── user.ts // token、角色、权限 │ ├── hooks │ └── usePermission.ts // 权限 Hook │ ├── components │ └── Permission.tsx // 按钮权限组件 │ └── utils └── auth.ts // token 工具十一、企业级最佳实践React Router v6 Redux对于使用React Router v6 Redux或 Zustand的中大型项目推荐采用以下职责划分模块职责数据来源登录认证校验 Token 是否存在、是否过期localStorage Redux路由守卫拦截未登录用户、校验页面访问权限Redux 中的用户信息和权限菜单权限根据后端返回的菜单列表动态渲染侧边栏后端菜单接口动态路由根据后端返回的路由配置生成可访问路由路由配置接口按钮权限控制按钮、操作入口是否显示或禁用后端权限码如user:add权限 Hook封装权限判断逻辑如usePermissionRedux/ZustandPermission组件在 JSX 中优雅地控制权限显示权限 Hook这种分层方式具有以下优点职责清晰认证、路由、菜单、按钮权限互不耦合。便于扩展新增角色或权限类型时只需调整权限配置和判断逻辑。符合企业后台实践适用于 React Ant Design、React Material UI 等常见后台管理系统也便于与 RBAC基于角色的访问控制模型结合。支持动态权限能够结合后端返回的数据实现菜单、路由和按钮权限的统一管理。如果你正在准备前端面试这套实现登录认证 路由守卫 动态路由 菜单权限 按钮权限 RBAC基本覆盖了 React 中后台项目关于权限控制的高频考点。