Wenn dasselbe Laravel-Projekt über mehrere Terminals (mobiles Terminal, Verwaltungsterminal ...) verfügt und alle JWT zur Benutzerüberprüfung verwenden müssen, Wenn mehrere Benutzertabellen vorhanden sind (normalerweise sind dies der Fall), muss eine Token-Isolierung durchgeführt werden. Andernfalls besteht das Problem, dass das Token auf der mobilen Seite auch die Verwaltungsseite anfordern kann, was dazu führt, dass der Benutzer seine Berechtigungen überschreitet.
Der Grund, warum dieses Problem auftritt, ist, dass das JWT-Token von Laravel standardmäßig nur den Wert des Primärschlüssels der Datentabelle speichert und nicht unterscheidet, um welche Tabelle es sich handelt. Solange also die im Token enthaltene ID in Ihrer Benutzertabelle vorhanden ist, führt dies zu einer unbefugten Überprüfung.
Werfen wir einen Blick auf das ursprüngliche Erscheinungsbild des JWT-Tokens von Laravel:
{ "iss": "http://your-request-url", "iat": 1558668215, "exp": 1645068215, "nbf": 1558668215, "jti": "XakIDuG7K0jeWGDi", "sub": 1, "prv": "92d5e8eb1b38ccd11476896c19b0e44512b2aacd" }
Das Unterfeld, das Daten trägt, ist das Unterfeld, und die anderen Felder sind die Verifizierungsfelder von JWT.
Wir sehen nur, dass der Wert von sub 1 ist, und es gibt nicht an, zu welcher Tabelle oder welchem Validator es gehört. Wenn dieses Token Ihre Verifizierungs-Middleware besteht, können Sie verschiedene Wächter verwenden, um den Benutzer mit der entsprechenden Tabellen-ID 1 zu erhalten (Informationen zum Wächter finden Sie in der Laravel-Dokumentation).
Um das Problem der Benutzerüberschreitung zu lösen, müssen wir nur unsere benutzerdefinierten Felder zum Token hinzufügen, um zu unterscheiden, welche Tabelle oder welcher Validator es generiert hat, und dann Ihre eigene Middleware schreiben, um dies zu überprüfen Unsere benutzerdefinierten Felder entsprechen unseren Erwartungen.
Wir wissen, dass das Benutzermodell zur Verwendung der JWT-Verifizierung die JWTSubject-Schnittstelle implementieren muss (der Code stammt aus dem JWT-Dokument):
<?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 []; } }
Wir können uns die Funktionen dieser beiden implementierten Methoden ansehen:
Als nächstes können wir unsere benutzerdefinierten Informationen zum Benutzermodell hinzufügen, das die Methode getJWTCustomClaims implementiert.
Administratormodell:
/** * 额外在 JWT 载荷中增加的自定义内容 * * @return array */ public function getJWTCustomClaims() { return ['role' => 'admin']; }
Mobiles Benutzermodell:
/** * 额外在 JWT 载荷中增加的自定义内容 * * @return array */ public function getJWTCustomClaims() { return ['role' => 'user']; }
Hier wird ein Rollenname als Benutzer-ID hinzugefügt.
Der vom Administrator generierte Token sieht so aus:
{ "iss": "http://your-request-url", "iat": 1558668215, "exp": 1645068215, "nbf": 1558668215, "jti": "XakIDuG7K0jeWGDi", "sub": 1, "prv": "92d5e8eb1b38ccd11476896c19b0e44512b2aacd", "role": "admin" }
Der vom mobilen Benutzer generierte Token sieht so aus:
{ "iss": "http://your-request-url", "iat": 1558668215, "exp": 1645068215, "nbf": 1558668215, "jti": "XakIDuG7K0jeWGDi", "sub": 1, "prv": "92d5e8eb1b38ccd11476896c19b0e44512b2aacd", "role": "user" }
Wir können sehen, dass es einen gibt mehr von uns hier Das hinzugefügte Rollenfeld entspricht unserem Benutzermodell.
Als nächstes schreiben wir selbst eine Middleware, um festzustellen, ob es die gewünschte Rolle ist. Wenn es nicht übereinstimmt, wird 401 gemeldet.
Hier ist eine global verwendbare Middleware (wird vor der Benutzerüberprüfungs-Middleware empfohlen):
<?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); } }
Registrieren Sie die 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, ];
Als nächstes fügen Sie die Route hinzu, die eine Benutzerüberprüfung erfordert. Fügen Sie unsere Middleware zur Gruppe hinzu:
Route::group([ 'middleware' => ['jwt.role:admin', 'jwt.auth'], ], function ($router) { // 管理员验证路由 // ... }); Route::group([ 'middleware' => ['jwt.role:user', 'jwt.auth'], ], function ($router) { // 移动端用户验证路由 // ... });
Damit ist die Isolierung der JWT-Benutzerüberprüfung für mehrere Tabellen abgeschlossen.
Weitere technische Artikel zu Laravel finden Sie in der Spalte Laravel-Tutorial, um mehr darüber zu erfahren!
Das obige ist der detaillierte Inhalt vonLaravel JWT Multi-Table-Validierungsisolation. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!