Heim >PHP-Framework >Laravel >Laravel JWT Multi-Table-Validierungsisolation

Laravel JWT Multi-Table-Validierungsisolation

步履不停
步履不停Original
2019-07-03 14:18:283698Durchsuche

Laravel JWT Multi-Table-Validierungsisolation

Warum Isolation erforderlich ist

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).

Lösung

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.

Benutzerdefinierte Informationen zum Token hinzufügen

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:

  • getJWTIdentifier: Ruft den Bezeichner ab, der in der JWT-Anweisung gespeichert wird. Tatsächlich müssen wir das Primärschlüsselfeld zurückgeben Der Name, der die Benutzertabelle identifiziert, ist die Primärschlüssel-ID.
  • getJWTCustomClaims: Gibt ein Array mit benutzerdefinierten Schlüssel-Wert-Paaren zurück, die der JWT-Deklaration hinzugefügt werden sollen hier ohne hinzugefügte benutzerdefinierte Informationen.

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.

JWT-Rollenüberprüfungs-Middleware schreiben

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);
    }
}

JWT-Rollenüberprüfungs-Überprüfungs-Middleware registrieren

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,
    ];

JWT-Rollenüberprüfungs-Middleware verwenden

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Warum Laravel wählen?Nächster Artikel:Warum Laravel wählen?