Laravel jwt multi-table validation isolation
Why do we need to isolate
When the same laravel project has multiple terminals (mobile terminal, management terminal...) and all need to use jwt for user verification , if there are multiple user tables (usually there are), token isolation needs to be done, otherwise there will be a problem that the token on the mobile side can also request the management side, causing the user to exceed his authority.
The reason why this problem occurs is that laravel's jwt token only stores the value of the primary key of the data table by default, and does not distinguish which table it is. So as long as the ID carried in the token exists in your user table, it will lead to unauthorized verification.
Let’s take a look at the original appearance of laravel’s jwt token:
{ "iss": "http://your-request-url", "iat": 1558668215, "exp": 1645068215, "nbf": 1558668215, "jti": "XakIDuG7K0jeWGDi", "sub": 1, "prv": "92d5e8eb1b38ccd11476896c19b0e44512b2aacd" }
The sub field that carries data is the sub field, and the other fields are the verification fields of jwt.
We only see that the value of sub is 1, and it does not indicate which table or validator it belongs to. When this token passes your verification middleware, you can use different guards to get the user with the corresponding table ID 1 (please check the laravel documentation to learn about guard).
Solution
To solve the problem of user overreaching, we only need to bring our custom fields on the token to distinguish which table or validator generated it, and then Write your own middleware to verify that our custom fields match our expectations.
Add custom information to token
We know that to use jwt verification, the user model must implement the JWTSubject interface (the code is taken from the jwt document):
<?php namespace App; use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements JWTSubject { use Notifiable; // Rest omitted for brevity /** * Get the identifier that will be stored in the subject claim of the JWT. * * @return mixed */ public function getJWTIdentifier() { return $this->getKey(); } /** * Return a key value array, containing any custom claims to be added to the JWT. * * @return array */ public function getJWTCustomClaims() { return []; } }
We can Take a look at the functions of these two implemented methods:
- getJWTIdentifier: Get the identifier that will be stored in the jwt statement. In fact, it requires us to return the primary key field name that identifies the user table. Here is what is returned Is the primary key 'id',
- getJWTCustomClaims: Returns an array containing custom key-value pairs to be added to the jwt declaration. An empty array is returned here without any custom information added.
Next we can add our custom information to the user model that implements the getJWTCustomClaims method.
Administrator model:
/** * 额外在 JWT 载荷中增加的自定义内容 * * @return array */ public function getJWTCustomClaims() { return ['role' => 'admin']; }
Mobile user model:
/** * 额外在 JWT 载荷中增加的自定义内容 * * @return array */ public function getJWTCustomClaims() { return ['role' => 'user']; }
A role name is added here as the user ID.
The token generated by the administrator will look like this:
{ "iss": "http://your-request-url", "iat": 1558668215, "exp": 1645068215, "nbf": 1558668215, "jti": "XakIDuG7K0jeWGDi", "sub": 1, "prv": "92d5e8eb1b38ccd11476896c19b0e44512b2aacd", "role": "admin" }
The token generated by the mobile user will look like this:
{ "iss": "http://your-request-url", "iat": 1558668215, "exp": 1645068215, "nbf": 1558668215, "jti": "XakIDuG7K0jeWGDi", "sub": 1, "prv": "92d5e8eb1b38ccd11476896c19b0e44512b2aacd", "role": "user" }
We can see that there is one more of ourselves here The added role field corresponds to our user model.
Next, we will write a middleware ourselves. After parsing the token, we will determine whether it is the role we want. If it matches, it will pass. If it does not match, it will report 401.
Write jwt role verification middleware
Here is a globally usable middleware (recommended to be used before user verification middleware):
<?php /** * Created by PhpStorm. * User: wlalala * Date: 2019-04-17 * Time: 13:55 */ namespace App\Http\Middleware; use Closure; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Http\Middleware\BaseMiddleware; class JWTRoleAuth extends BaseMiddleware { /** * Handle an incoming request. * * @param $request * @param Closure $next * @param null $role * @return mixed */ public function handle($request, Closure $next, $role = null) { try { // 解析token角色 $token_role = $this->auth->parseToken()->getClaim('role'); } catch (JWTException $e) { /** * token解析失败,说明请求中没有可用的token。 * 为了可以全局使用(不需要token的请求也可通过),这里让请求继续。 * 因为这个中间件的责职只是校验token里的角色。 */ return $next($request); } // 判断token角色。 if ($token_role != $role) { throw new UnauthorizedHttpException('jwt-auth', 'User role error'); } return $next($request); } }
Register jwt role verification Verification middleware
Register the middleware in app/Http/Kernel.php:
/** * The application's route middleware. * * These middleware may be assigned to groups or used individually. * * @var array */ protected $routeMiddleware = [ // ...省略 ... // 多表jwt验证校验 'jwt.role' => \App\Http\Middleware\JWTRoleAuth::class, ];
Use jwt role verification middleware
Next, add the route that requires user verification Add our middleware to the group:
Route::group([ 'middleware' => ['jwt.role:admin', 'jwt.auth'], ], function ($router) { // 管理员验证路由 // ... }); Route::group([ 'middleware' => ['jwt.role:user', 'jwt.auth'], ], function ($router) { // 移动端用户验证路由 // ... });
This completes jwt multi-table user verification isolation.
For more Laravel related technical articles, please visit the Laravel Tutorial column to learn!
The above is the detailed content of Laravel jwt multi-table validation isolation. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Method for obtaining the return code when Laravel email sending fails. When using Laravel to develop applications, you often encounter situations where you need to send verification codes. And in reality...

How to implement the table function of custom click to add data in dcatadmin (laravel-admin) When using dcat...

The impact of sharing of Redis connections in Laravel framework and select methods When using Laravel framework and Redis, developers may encounter a problem: through configuration...

Custom tenant database connection in Laravel multi-tenant extension package stancl/tenancy When building multi-tenant applications using Laravel multi-tenant extension package stancl/tenancy,...

LaravelEloquent Model Retrieval: Easily obtaining database data EloquentORM provides a concise and easy-to-understand way to operate the database. This article will introduce various Eloquent model search techniques in detail to help you obtain data from the database efficiently. 1. Get all records. Use the all() method to get all records in the database table: useApp\Models\Post;$posts=Post::all(); This will return a collection. You can access data using foreach loop or other collection methods: foreach($postsas$post){echo$post->

How to check the validity of Redis connections in Laravel6 projects is a common problem, especially when projects rely on Redis for business processing. The following is...

A problem of duplicate class definition during Laravel database migration occurs. When using the Laravel framework for database migration, developers may encounter "classes have been used...

Laravel is a PHP framework for easy building of web applications. It provides a range of powerful features including: Installation: Install the Laravel CLI globally with Composer and create applications in the project directory. Routing: Define the relationship between the URL and the handler in routes/web.php. View: Create a view in resources/views to render the application's interface. Database Integration: Provides out-of-the-box integration with databases such as MySQL and uses migration to create and modify tables. Model and Controller: The model represents the database entity and the controller processes HTTP requests.
