如何在React项目中实现基于角色的路由访问控制?
基于角色的访问控制实现方案
核心问题分析
当前代码未对路由的allowedRoles配置做权限校验,仅直接渲染路由组件,导致角色控制失效。我们需要在路由渲染环节加入权限判断,结合useAuth返回的用户角色实现访问控制。
解决方案步骤
1. 统一角色字符串格式
先修改routes.jsx中的allowedRoles为小写,与useAuth返回的status格式保持一致,避免大小写匹配错误:
import Overview from "./views/Overview "; import Teams from "./views/Teams "; import Apps from "./views/Apps "; const dashRoutes = [ { path: "/overview", element: <Overview />, layout: "/dashboard", allowedRoles: ["admin"] }, { path: "/teams", element: <Teams />, layout: "/dashboard", allowedRoles: ["admin"] }, { path: "/apps", element: <Apps />, layout: "/dashboard", allowedRoles: ["admin", "engineer"] }, ]; export default dashRoutes;
2. 修改Dashboard组件加入权限校验
在Dashboard组件中完成两步校验:用户是否登录、用户角色是否匹配路由权限:
import { Navigate, Route, Routes } from "react-router-dom"; import routes from "#routes"; import useAuth from "../hooks/useAuth"; import { ChakraProvider } from "@chakra-ui/react"; import theme from "../theme"; export default function Dashboard() { const { status } = useAuth(); // 未登录用户直接跳转登录页 if (status === "Operations") { return <Navigate to="/auth/login" />; } const getRoute = () => { return window.location.pathname !== "/dashboard/full-screen-maps"; }; const getRoutes = (routes) => { return routes.map((prop, key) => { if (prop.layout === "/dashboard") { let element = prop.element; // 校验当前用户是否拥有路由访问权限 if (prop.allowedRoles) { const hasPermission = prop.allowedRoles.includes(status); // 无权限则跳转到未授权页面(可替换为现有404路由) element = hasPermission ? prop.element : <Navigate to="/auth/unauthorized" />; } return <Route path={prop.path} element={element} key={key} />; } else { return null; } }); }; return ( <ChakraProvider theme={theme} resetCss={false}> {getRoute() ? ( <Routes> {getRoutes(routes)} <Route path="/dashboard" element={<Navigate to="/dashboard/overview" />} /> <Route path="*" element={<Navigate to="/auth/notfound" />} /> </Routes> ) : null} </ChakraProvider> ); }
关键修改说明
- 全局登录校验:在组件渲染前判断用户是否为未登录状态(
status === "Operations"),直接跳转登录页 - 路由权限校验:遍历路由时,对带有
allowedRoles的路由,检查当前用户角色是否在允许列表中,无权限则跳转至指定页面 - 格式统一:通过统一角色字符串大小写,避免因大小写不一致导致的匹配失败
内容的提问来源于stack exchange,提问作者Damilola Adegbemile
相关产品推荐
相关产品推荐

