Heim >PHP-Framework >Laravel >Analyse der Dingo- und JWT-Authentifizierung in Laravel8

Analyse der Dingo- und JWT-Authentifizierung in Laravel8

藏色散人
藏色散人nach vorne
2021-05-27 15:33:103140Durchsuche

Die folgende Tutorial-Kolumne von Laravel stellt Ihnen die Dingo- und JWT-Authentifizierung in Laravel8 vor. Ich hoffe, dass sie Freunden in Not hilfreich sein wird!

1 Was ist Dingo? Das Dingo-API-Paket ist ein Restful-Toolkit für Laravel und Lumen. Es kann mit JWT-Komponenten zusammenarbeiten, um die Benutzerauthentifizierung schnell abzuschließen, und kann gleichzeitig Daten und Ausnahmen erfassen, die während des Betriebs generiert werden kann entsprechend reagieren.

Hauptfunktionen:


Router-Versions-Routing-Versionsverwaltung
  1. http-Ausnahme-Ausnahmebehandlung
  2. Response-Transformations-Antwortformat
  3. 1 Dingo installieren
Installieren Sie das Dingo-Erweiterungspaket über Composer im Laravel-Stammverzeichnis. Die spezifischen Befehle sind wie folgt:
composer require dingo/api

Verwenden Sie den folgenden Befehl, um die API-Konfigurationsdatei in der Konfigurationsdatei zu veröffentlichen:

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

2 Dingo konfigurieren

Über die API-Konfigurationsinformationen von Dingo können wir sie in der .env-Datei konfigurieren
# dingo
# API_SUBTYPE —— 项目的简称;
API_SUBTYPE=lms
# API_PREFIX —— 与 API_DOMAIN 二选一,路由的前缀,例如设置为 api
API_PREFIX=api
# 定义版本
API_VERSION=v1
# 是否开启调试模式
API_DEBUG=true

Detaillierte Konfiguration über Dingo Bitte überprüfen Sie die relevanten Dokumente: https://learnku.com/docs/dingo-api/2.0.0/Configuration/1444

2 Was ist JWT? JWT, der vollständige Name von JSON Web Tokens, ist sehr leichtgewichtig Spezifikation: Diese Spezifikation ermöglicht die sichere und zuverlässige Übertragung von Informationen zwischen Benutzern und Servern. Die Hauptverwendungsszenarien sind: Authentifizierung und Datenaustausch.

1 JWT installieren Spezifische Befehle lauten wie folgt:

composer require tymon/jwt-auth

Verwenden Sie den folgenden Befehl, um die API-Konfigurationsdatei in der Konfigurationsdatei zu veröffentlichen:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
2 Konfigurieren Sie JWT

Generieren Sie den JWT-Verschlüsselungsschlüssel in der .env-Datei.

php artisan jwt:secret

Ändern Sie die config/api.php-Konfiguration

'auth' => [
    'jwt' => 'Dingo\Api\Auth\Provider\JWT',
],
Ändern Sie die config/auth.php-Konfiguration
'defaults' => [
        #注:这里修改改了默认的配置,默认是web
        'guard' => 'api',
        'passwords' => 'users',
    ],
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

Eine detaillierte Konfiguration von jwt finden Sie in den entsprechenden Dokumenten: https://jwt-auth.readthedocs.io/en/ entwickeln/

3 Demonstration des zugehörigen Codes

Erstellen Sie RefreshToken Middleware für die Aktualisierung des Token-Ablaufs

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;

class RefreshToken extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // 检查此次请求中是否带有 token,如果没有则抛出异常。
        $this->checkForToken($request);

        // 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException  异常
        try {
            // 检测用户的登录状态,如果正常则通过
            if ($this->auth->parseToken()->authenticate()) {
                return $next($request);
            }
            throw new UnauthorizedHttpException('jwt-auth', '未登录');
        } catch (TokenExpiredException $exception) {
            // 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
            try {
                // 刷新用户的 token
                $token = $this->auth->refresh();
                // 使用一次性登录以保证此次请求的成功
                Auth::guard('api')
                    ->onceUsingId($this->auth->manager()
                        ->getPayloadFactory()
                        ->buildClaimsCollection()
                        ->toPlainArray()['sub']);
            } catch (JWTException $exception) {
                // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
                throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
            }
        }

        // 在响应头中返回新的 token
        return $this->setAuthenticationHeader($next($request), $token);
    }
}

Das Benutzermodell muss zwei Methoden implementieren: getJWTIdentifier() und getJWTCustomClaims()

<?php

namespace App\Models;

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

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    public $table = "user";

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        &#39;name&#39;, &#39;email&#39;, &#39;password&#39;,&#39;phone&#39;,&#39;status&#39;,&#39;create_time&#39;,&#39;addr_id&#39;
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        &#39;password&#39;, &#39;remember_token&#39;,
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
//        &#39;email_verified_at&#39; => 'datetime',
    ];

    /**
     * 指示是否自动维护时间戳
     *
     * @var bool
     */
    public $timestamps = false;

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    public function getJWTCustomClaims()
    {
        return [];
    }
}
?>

Erstellen Sie einen UserController für die Authentifizierung und andere verwandte Vorgänge

<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\User;
use Dingo\Api\Routing\Helpers;
use Illuminate\Http\Request;

class UserController extends Controller
{
    use Helpers;

    public function __construct()
    {
       //除去token验证的方法
       $this->middleware('refresh.token', [
            'except' => [
                'login',
            ],
        ]);
    }


    /**用户登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function login(Request $request)
    {
        $phone = $request->get('phone');

        $user = User::where('phone', $phone)->first();

//        //attempt貌似无法验证其他字段,如需用其他字段鉴权使用login()
//        $credentials = request(['name','password']);
//        if (!$token = auth()->attempt($credentials)) {
//            return response()->json(['error' => 'Unauthorized'], 401);
//        }

        //只要是user实例就可以通过login鉴权
        if (! $token = auth()->login($user)) {
            return response()->json([
                "restful" => false,
                "message" => "账号错误",
            ]);
        }

        //获取用户信息
        $user = $this->user();
        $key = "user::info::".$user->id;
        //Redis缓存用户信息3600秒
        Redis::set($key,serialize($user->original),"EX",3600);

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

    /**获取用户
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function user()
    {
        return response()->json(auth()->user());
    }

    /**用户退出
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth()->logout();

        return response()->json(["message" => "退出成功"]);
    }

    /**用户登录状态刷新
     * Refresh a token.
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth()->refresh());
    }

    /**返回值
     * @param $token
     * @return array
     */
    protected function respondWithToken($token)
    {
        return [
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth()->factory()->getTTL() * 60,
            'restful' => true
        ];
    }
}

Das obige ist der detaillierte Inhalt vonAnalyse der Dingo- und JWT-Authentifizierung in Laravel8. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jianshu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen