ReactJS路由中如何实现用户等级校验与路由权限控制
React Router v5 路由守卫实现方案
从你贴的代码里的Switch组件判断,你当前用的是React Router v5版本,直接封装可复用的高阶路由组件替换原生Route即可实现需求,不需要改动原有路由的整体结构。
1. 封装基础登录认证守卫
这个组件负责统一校验登录态,未登录用户自动跳转登录页,同时留存原始访问路径:
import { Route, Redirect } from 'react-router-dom'; // 基础登录守卫:所有需要登录才能访问的路由都用这个组件 const AuthRoute = ({ component: Component, ...rest }) => { // 登录态判断逻辑替换成你项目实际的取值方式即可,支持从redux、context、本地存储读取 const isLoggedIn = !!localStorage.getItem('access_token'); return ( <Route {...rest} render={(routeProps) => { if (!isLoggedIn) { // 未登录时,将目标路径编码后拼在登录页url参数里 return ( <Redirect to={{ pathname: '/login', search: `?redirect=${encodeURIComponent(routeProps.location.pathname)}` }} /> ); } // 校验通过直接渲染目标页面 return <Component {...routeProps} />; }} /> ); };
在登录页的登录成功回调里,加一段跳转逻辑,就能实现登录后回到原目标页:
// 登录接口请求成功后执行 const searchParams = new URLSearchParams(window.location.search); const targetPath = searchParams.get('redirect') || '/'; // 没有留存路径就默认跳首页 props.history.push(decodeURIComponent(targetPath));
2. 封装管理员权限守卫(adminGuard)
在登录校验的基础上增加角色/权限判断,拦截无权限访问:
// 权限守卫:需要特定角色/权限才能访问的路由用这个组件 const ProtectedRoute = ({ component: Component, allowedRoles = [], ...rest }) => { const isLoggedIn = !!localStorage.getItem('access_token'); // 当前用户信息替换成你项目实际的取值来源 const currentUser = JSON.parse(localStorage.getItem('user_info') || '{}'); return ( <Route {...rest} render={(routeProps) => { // 先过登录校验 if (!isLoggedIn) { return ( <Redirect to={{ pathname: '/login', search: `?redirect=${encodeURIComponent(routeProps.location.pathname)}` }} /> ); } // 再校验角色权限 if (allowedRoles.length && !allowedRoles.includes(currentUser.role)) { // 权限不足跳转无权限提示页,也可以根据需求改成跳首页 return <Redirect to="/403" />; } // 校验通过渲染目标页面 return <Component {...routeProps} />; }} /> ); };
3. 替换原有路由配置
把你原来的路由表按照页面访问权限,替换成对应的守卫组件即可:
render() { return ( <div> <main> <Switch> {/* 公开页面:不需要登录,保留原生Route */} <Route exact path='/' component={Wizard}/> <Route exact path='/login' component={Login}/> <Route exact path='/403' component={NoPermission}/> {/* 管理员页面:用权限守卫,传入允许访问的角色列表 */} <ProtectedRoute exact path='/admin' component={Admin} allowedRoles={['admin']} /> {/* 普通登录即可访问的页面:用基础登录守卫 */} <AuthRoute exact path='/details' component={Details}/> {/* 其余路由按照权限规则对应替换即可 */} </Switch> </main> </div> ) }
注意事项
- 上述示例用localStorage存储登录态和用户信息是为了简化演示,实际项目中如果使用Redux、Context等全局状态方案,只需要替换守卫里的取值逻辑,整体代码结构不需要改动。
- 如果需要更细粒度的权限控制(比如按钮级、接口权限点控制),只需要修改
ProtectedRoute里的权限判断逻辑即可,守卫的整体复用逻辑不变。 - 前端路由守卫仅用于提升用户体验,所有后端接口必须单独做权限校验,前端的权限控制可以被绕过,不能作为安全防线。
内容的提问来源于stack exchange,提问作者Sonnich Jensen
相关产品推荐
相关产品推荐

