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

ReactJs/Laravel路由保护咨询:登录用户及角色权限控制实现

React + Laravel 实现路由保护与基于角色的身份验证

一、Laravel 后端实现

1. 配置 API 身份认证(以 JWT 为例)

先安装并配置 tymon/jwt-auth 包,这是 API 场景下常用的身份验证方案:

composer require tymon/jwt-auth
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
php artisan jwt:secret

修改用户模型,实现 JWTSubject 接口,让 JWT 能携带用户角色信息:

use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    // 原有代码保持不变

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [
            'role' => $this->role // 假设用户表包含 `role` 字段,值如 'admin'/'user'
        ];
    }
}

2. 编写角色验证中间件

创建专门校验用户角色的中间件:

php artisan make:middleware CheckRole

在 app/Http/Middleware/CheckRole.php 中编写逻辑:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;

class CheckRole
{
    public function handle(Request $request, Closure $next, ...$roles)
    {
        try {
            $user = JWTAuth::parseToken()->authenticate();
        } catch (\Exception $e) {
            return response()->json(['message' => '未授权'], 401);
        }

        if (!in_array($user->role, $roles)) {
            return response()->json(['message' => '权限不足'], 403);
        }

        return $next($request);
    }
}

在 app/Http/Kernel.php 中注册中间件:

protected $routeMiddleware = [
    // 原有中间件保持不变
    'jwt.auth' => \Tymon\JWTAuth\Http\Middleware\Authenticate::class,
    'role' => \App\Http\Middleware\CheckRole::class,
];

3. 保护 API 路由

在 routes/api.php 中划分路由权限:

// 公开路由:登录、注册
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);

// 需要登录才能访问的路由组
Route::middleware('jwt.auth')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);

    // 需要 admin 角色才能访问的路由组
    Route::middleware('role:admin')->group(function () {
        Route::get('/admin/users', [AdminController::class, 'getUsers']);
    });
});

登录接口示例(AuthController):

public function login(Request $request)
{
    $credentials = $request->only('email', 'password');

    if (!$token = auth('api')->attempt($credentials)) {
        return response()->json(['error' => '用户名或密码错误'], 401);
    }

    return $this->respondWithToken($token);
}

protected function respondWithToken($token)
{
    return response()->json([
        'access_token' => $token,
        'token_type' => 'bearer',
        'expires_in' => auth('api')->factory()->getTTL() * 60,
        'user' => auth('api')->user()
    ]);
}

二、React 前端实现

1. 封装身份验证工具类

创建 src/utils/auth.js,管理 token 和用户信息:

// 存储 token
export const setToken = (token) => localStorage.setItem('token', token);
// 获取 token
export const getToken = () => localStorage.getItem('token');
// 退出登录,清除本地数据
export const logout = () => {
    localStorage.removeItem('token');
    localStorage.removeItem('user');
};
// 存储用户信息
export const setUser = (user) => localStorage.setItem('user', JSON.stringify(user));
// 获取用户信息
export const getUser = () => JSON.parse(localStorage.getItem('user'));
// 判断是否已登录
export const isAuthenticated = () => !!getToken();
// 判断用户是否拥有指定角色
export const hasRole = (role) => {
    const user = getUser();
    return user && user.role === role;
};

2. 编写路由守卫组件

创建通用登录守卫 src/components/ProtectedRoute.jsx:

import { Navigate, Outlet } from 'react-router-dom';
import { isAuthenticated } from '../utils/auth';

const ProtectedRoute = () => {
    if (!isAuthenticated()) {
        return <Navigate to="/login" replace />;
    }
    return <Outlet />;
};

export default ProtectedRoute;

创建 admin 角色专属守卫 src/components/AdminRoute.jsx:

import { Navigate, Outlet } from 'react-router-dom';
import { isAuthenticated, hasRole } from '../utils/auth';

const AdminRoute = () => {
    if (!isAuthenticated()) {
        return <Navigate to="/login" replace />;
    }
    if (!hasRole('admin')) {
        return <Navigate to="/403" replace />;
    }
    return <Outlet />;
};

export default AdminRoute;

3. 配置 React 路由

在 App.jsx 中设置路由规则:

import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import Login from './pages/Login';
import Dashboard from './pages/Dashboard';
import AdminPanel from './pages/AdminPanel';
import Forbidden from './pages/Forbidden';
import NotFound from './pages/NotFound';
import ProtectedRoute from './components/ProtectedRoute';
import AdminRoute from './components/AdminRoute';

function App() {
    return (
        <Router>
            <Routes>
                {/* 公开路由 */}
                <Route path="/login" element={<Login />} />
                <Route path="/403" element={<Forbidden />} />
                <Route path="/404" element={<NotFound />} />

                {/* 需要登录的路由组 */}
                <Route element={<ProtectedRoute />}>
                    <Route path="/dashboard" element={<Dashboard />} />

                    {/* 需要 admin 角色的路由组 */}
                    <Route element={<AdminRoute />}>
                        <Route path="/admin" element={<AdminPanel />} />
                    </Route>
                </Route>

                {/* 默认跳转规则 */}
                <Route path="/" element={<Navigate to="/dashboard" replace />} />
                <Route path="*" element={<Navigate to="/404" replace />} />
            </Routes>
        </Router>
    );
}

export default App;

4. 配置 API 请求拦截器

创建 src/utils/axios.js,自动携带 token 并处理未授权情况:

import axios from 'axios';
import { getToken, logout } from './auth';

const api = axios.create({
    baseURL: 'http://你的LaravelAPI地址/api',
});

// 请求拦截:自动添加 token 到请求头
api.interceptors.request.use(
    (config) => {
        const token = getToken();
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    (error) => Promise.reject(error)
);

// 响应拦截:处理 token 过期或未授权
api.interceptors.response.use(
    (response) => response,
    (error) => {
        if (error.response.status === 401) {
            logout();
            window.location.href = '/login';
        }
        return Promise.reject(error);
    }
);

export default api;

内容的提问来源于stack exchange,提问作者WILBERT JOSH ALFORNON

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:55:10