Laravel JWT多用户接口权限拦截完整代码

浅明大大_9803

浅明大大_9803

2026-08-15

736人浏览

原创

laravel jwt多用户权限拦截需区分用户表token并细粒度控制:1.各模型通过getjwtcustomclaims()注入guard标识;2.自定义checkjwtguard中间件校验payload中guard值;3.路由按guard分组绑定jwt.auth与jwt.guard中间件;4.gate权限闭包中严格判断模型实例类型。

laravel jwt多用户接口权限拦截完整代码

要实现 Laravel 中 JWT 多用户接口的权限拦截,核心是解决两个问题:一是区分不同用户表(如 users、admins)生成的 Token 不混用;二是对不同守卫(guard)下的请求做细粒度权限控制(如“仅管理员可访问 /admin/users”)。下面给出完整、可直接落地的代码结构,不含冗余说明,聚焦关键文件与逻辑。

1. 多用户模型隔离:为每个用户表添加自定义 claim

以 Admin 模型为例(app/Models/Admin.php):

```php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class Admin extends Authenticatable implements JWTSubject
{
protected $table = 'admins';
protected $guarded = [];

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

public function getJWTCustomClaims()
{
// 关键:标识该 token 来自 admins 表
return ['guard' => 'admin'];
}
}

User 模型同理,返回 ['guard' => 'web'] 或 ['guard' => 'api'],确保字段值唯一且可识别。

2. 自定义中间件:校验 Token 中的 guard 声明

运行:php artisan make:middleware CheckJwtGuard

编辑 app/Http/Middleware/CheckJwtGuard.php:

```php
namespace App\Http\Middleware;

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

class CheckJwtGuard
{
public function handle(Request $request, Closure $next, string $expectedGuard)
{
try {
$token = JWTAuth::parseToken();
$payload = $token->getPayload();
// 从 payload 提取自定义 guard 字段
$actualGuard = $payload['guard'] ?? null;

if ($actualGuard !== $expectedGuard) {
return response()->json([
'message' => 'Invalid token guard'
], 401);
}
} catch (JWTException $e) {
return response()->json([
'message' => 'Token is invalid or expired'
], 401);
}

return $next($request);
}
}

在 app/Http/Kernel.php 的 $routeMiddleware 中注册:

Laravel Creem Agent
Laravel Creem Agent

Creem 支付商店助理 — 查询订阅、客户、交易、产品,执行心跳检查,管理本地 Laravel支付商店。

下载
```php
'jwt.guard' => \App\Http\Middleware\CheckJwtGuard::class,
```

3. 路由分组 + 守卫绑定 + 权限检查

在 routes/api.php 中:

```php
// 管理端接口(强制 token 来自 admins 表)
Route::prefix('admin')->group(function () {
Route::middleware(['jwt.auth', 'jwt.guard:admin'])->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard']);
Route::get('/users', [AdminController::class, 'listUsers'])
->middleware('can:manage-users'); // 使用 Gate 权限
});
});

// 用户端接口(强制 token 来自 users 表)
Route::prefix('api')->group(function () {
Route::middleware(['jwt.auth', 'jwt.guard:api'])->group(function () {
Route::get('/profile', [UserController::class, 'profile']);
Route::post('/comment', [PostController::class, 'store'])
->middleware('can:create-comment');
});
});
```

4. Gate 权限定义(支持多用户类型)

在 app/Providers/AuthServiceProvider.php 的 boot() 方法中:

```php
use Illuminate\Support\Facades\Gate;

Gate::define('manage-users', function ($user) {
// 区分模型类型,避免 User 和 Admin 混淆
return $user instanceof \App\Models\Admin && $user->role === 'super_admin';
});

Gate::define('create-comment', function ($user) {
return $user instanceof \App\Models\User && $user->status === 'active';
});
```

注意:权限闭包中必须显式判断模型实例类型,不能只依赖 $user->role —— 因为不同表可能有同名字段,但含义完全不同。

5. 登录控制器示例(带 guard 标识写入)

app/Http/Controllers/AdminController.php:

```php
use Tymon\JWTAuth\Facades\JWTAuth;

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

if (!$token = auth('admin')->attempt($credentials)) {
return response()->json(['message' => 'Unauthorized'], 401);
}

return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('admin')->factory()->getTTL() * 60
]);
}
```

其中 auth('admin') 对应 config/auth.php 中已配置的 admin guard,驱动为 jwt,provider 指向 admins 模型。

不复杂但容易忽略:所有中间件顺序必须是 jwt.auth 在前、jwt.guard 在后;Gate 权限判断必须基于具体模型类而非通用 Auth::user() 返回值类型;Token 一旦签发就不可更改 claim,所以登录时务必确保 getJWTCustomClaims() 返回正确值。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

laravel

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

10344

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

6101

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2115

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3828

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4534

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3571

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

5077

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

3982

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

11942

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 204人学习

Composer手册
Composer手册

共0课时 | 0人学习