react路由如何做权限校验
路由权限校验的实现方法
在React应用中实现路由权限校验通常需要结合路由库(如React Router)和状态管理工具(如Redux或Context API)。以下是几种常见的实现方式:
使用高阶组件(HOC)包装路由
创建高阶组件来检查用户权限,决定是否渲染目标组件或重定向到登录页:
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
<Route
{...rest}
render={props =>
isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
使用方式:
<PrivateRoute
path="/dashboard"
component={Dashboard}
isAuthenticated={user.isLoggedIn}
/>
在路由配置中集中管理权限
定义路由配置数组,包含权限要求:
const routes = [
{ path: '/', component: HomePage, public: true },
{ path: '/admin', component: AdminPage, roles: ['admin'] },
{ path: '/profile', component: ProfilePage, authRequired: true }
];
渲染时根据配置检查权限:
{routes.map((route) => {
if (route.public) return <Route {...route} />;
if (route.authRequired && !isLoggedIn) return <Redirect to="/login" />;
if (route.roles && !hasRequiredRole(route.roles)) return <Redirect to="/403" />;
return <Route {...route} />;
})}
使用React Router v6的loader功能
v6版本引入了loader机制,可以在路由加载前执行权限检查:
const router = createBrowserRouter([
{
path: '/protected',
element: <ProtectedPage />,
loader: async () => {
if (!await checkAuth()) {
throw redirect('/login');
}
return null;
}
}
]);
结合Context API管理权限状态
创建全局AuthContext存储用户权限:
const AuthContext = createContext();
function useAuth() {
return useContext(AuthContext);
}
function App() {
const [user, setUser] = useState(null);
return (
<AuthContext.Provider value={{ user }}>
<Routes>
<Route path="/admin" element={
<RequireAuth roles={['admin']}>
<AdminPage />
</RequireAuth>
}/>
</Routes>
</AuthContext.Provider>
);
}
动态菜单渲染
根据权限过滤可访问的路由,生成导航菜单:
function NavMenu() {
const { user } = useAuth();
const filteredRoutes = allRoutes.filter(route =>
!route.requiredRole ||
user?.roles.includes(route.requiredRole)
);
return (
<nav>
{filteredRoutes.map(route => (
<Link to={route.path}>{route.label}</Link>
))}
</nav>
);
}
错误边界处理
为无权限访问提供友好提示:
function RequireAuth({ children, roles }) {
const { user } = useAuth();
if (!user) return <Navigate to="/login" />;
if (roles && !roles.some(r => user.roles.includes(r))) {
return <UnauthorizedPage />;
}
return children;
}
服务端校验补充
尽管前端做了校验,服务端仍需对每个请求进行权限验证:
// Express中间件示例
function checkRole(requiredRole) {
return (req, res, next) => {
if (!req.user.roles.includes(requiredRole)) {
return res.status(403).send('Forbidden');
}
next();
};
}
实现路由权限校验时,建议将权限逻辑集中管理,避免分散在各个组件中。根据应用复杂度选择合适的方案,简单应用可以使用HOC方式,复杂系统建议采用路由配置集中管理。







