You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Symfony 5.4与React 18.16中实现Admin角色路由权限及Token传输

Symfony 5.4 + React 18.16 Token路由权限控制完整流程

这不是二选一的问题,后端(Symfony)和前端(React)需要配合完成权限控制,具体步骤如下:

一、Symfony后端处理

  1. 确保Token包含角色信息
    你已经能在Postman拿到Token,现在要保证Token的payload里包含用户角色(比如ROLE_ADMIN)。如果用LexikJWTAuthenticationBundle,只需在User实体的getRoles()方法返回正确角色数组,Bundle会自动把角色加入JWT payload。
  2. 保护后端API路由
    在config/packages/security.yaml里配置权限规则,限制Admin角色才能访问特定接口:
    security:
        # 其他配置...
        access_control:
            - { path: ^/api/admin, roles: ROLE_ADMIN }
            - { path: ^/api/public, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    
    非Admin角色的请求访问/api/admin路径时,会直接返回403权限错误。
  3. 可选:统一权限异常处理
    可以创建一个异常监听器,把Symfony的权限异常转换成JSON格式响应,方便前端处理:
    // src/EventListener/AuthenticationExceptionListener.php
    namespace App\EventListener;
    
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpKernel\Event\ExceptionEvent;
    use Symfony\Component\Security\Core\Exception\AccessDeniedException;
    
    class AuthenticationExceptionListener
    {
        public function onKernelException(ExceptionEvent $event): void
        {
            $exception = $event->getThrowable();
            if ($exception instanceof AccessDeniedException) {
                $response = new JsonResponse([
                    'message' => '无权限访问此资源'
                ], 403);
                $event->setResponse($response);
            }
        }
    }
    
    不需要额外自定义控制器,Symfony自带的Security组件已经能完成权限校验。

二、React前端处理

  1. 存储Token
    登录请求成功后,把后端返回的Token存在localStorage或sessionStorage中:
    // 登录请求示例
    const login = async (credentials) => {
        const response = await axios.post('/api/login', credentials);
        localStorage.setItem('authToken', response.data.token);
    };
    
  2. 全局请求拦截器
    用Axios设置请求拦截器,给所有需要权限的请求自动带上Token:
    import axios from 'axios';
    
    axios.interceptors.request.use(config => {
        const token = localStorage.getItem('authToken');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    });
    
  3. 前端路由守卫
    用react-router-dom v6自定义路由组件,校验用户角色是否有权限访问Admin页面:
    import { Navigate, Outlet } from 'react-router-dom';
    
    const AdminRoute = () => {
        // 解码JWT获取用户角色
        const getCurrentUser = () => {
            const token = localStorage.getItem('authToken');
            if (!token) return null;
            // 解码JWT的payload部分
            const payload = JSON.parse(atob(token.split('.')[1]));
            return payload;
        };
    
        const user = getCurrentUser();
        const isAdmin = user?.roles?.includes('ROLE_ADMIN');
    
        // 有权限则渲染子路由,否则跳转到登录页
        return isAdmin ? <Outlet /> : <Navigate to="/login" replace />;
    };
    
    // 路由配置中使用
    function AppRoutes() {
        return (
            <Routes>
                <Route path="/login" element={<LoginPage />} />
                <Route path="/admin" element={<AdminRoute />}>
                    <Route index element={<AdminDashboard />} />
                    <Route path="users" element={<UserManagement />} />
                    {/* 其他Admin专属页面 */}
                </Route>
                <Route path="/" element={<PublicHome />} />
            </Routes>
        );
    }
    
  4. 权限错误处理
    设置响应拦截器,当后端返回403时,清除Token并跳转到登录页:
    axios.interceptors.response.use(
        response => response,
        error => {
            if (error.response?.status === 403) {
                localStorage.removeItem('authToken');
                window.location.href = '/login';
            }
            return Promise.reject(error);
        }
    );
    

内容的提问来源于stack exchange,提问作者Eva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:07:10