>PHP 프레임워크 >Laravel >laravel8의 dingo 및 jwt 인증 분석

laravel8의 dingo 및 jwt 인증 분석

藏色散人
藏色散人앞으로
2021-05-27 15:33:103140검색

다음 튜토리얼 칼럼인 laravel에서는 laravel8의 dingo 및 jwt 인증에 대해 소개하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!

1 dingo란

dingo api 패키지는 laravel 및 lumen용으로 제공되는 Restful 툴킷으로, jwt 구성 요소와 함께 작동하여 사용자 인증을 빠르게 완료하는 동시에 작업 중에 생성되는 데이터 및 예외를 캡처할 수 있습니다. 그에 따라 대응할 수 있습니다.
주요 기능:

  1. 라우터 버전 라우팅 버전 관리
  2. http 예외 예외 처리
  3. 응답 변환 변환 응답 형식
1 dingo 설치

laravel 루트 디렉터리에 작곡가를 통해 dingo 확장 패키지를 설치합니다.

composer require dingo/api

다음 명령을 사용하여 API 구성 파일을 구성 파일에 게시합니다.

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
2 dingo 구성

dingo의 api 구성 정보는 .env 파일에서 구성할 수 있습니다

# dingo
# API_SUBTYPE —— 项目的简称;
API_SUBTYPE=lms
# API_PREFIX —— 与 API_DOMAIN 二选一,路由的前缀,例如设置为 api
API_PREFIX=api
# 定义版本
API_VERSION=v1
# 是否开启调试模式
API_DEBUG=true

에 대한 자세한 구성 dingo 관련 문서를 확인하세요: https://learnku.com/docs/dingo-api/2.0.0/Configuration/1444

2 JSON Web Token의 전체 이름인 JWT

jwt는 매우 가볍습니다. 이 사양을 통해 우리는 jwt를 사용하여 사용자와 서버 간에 안전하고 신뢰할 수 있는 정보를 전송할 수 있습니다. 주요 사용 시나리오는 다음과 같습니다. 인증 및 데이터 교환

1 JWT 설치

laravel 루트 디렉터리에 작곡가를 통해 jwt 확장 패키지를 설치합니다. 특정 명령은 다음과 같습니다.

composer require tymon/jwt-auth

다음 명령을 사용하여 API 구성 파일을 구성 파일에 게시합니다.

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

.env 파일에 jwt 암호화 키를 생성합니다. 특정 명령은 다음과 같습니다.

php artisan jwt:secret

config/api.php 구성 수정

'auth' => [
    'jwt' => 'Dingo\Api\Auth\Provider\JWT',
],

config/auth.php 구성 수정

'defaults' => [
        #注:这里修改改了默认的配置,默认是web
        'guard' => 'api',
        'passwords' => 'users',
    ],
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

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

jwt의 자세한 구성은 관련 문서를 참조하세요: https://jwt-auth.readthedocs.io/en/ 개발/

3 관련 코드 데모

토큰 만료 새로고침을 위한 RefreshToken 미들웨어 생성

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

사용자 모델은 getJWTIdentifier() 및 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 [];
    }
}
?>

인증 및 기타 관련 작업을 위한 UserController 생성

<?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
        ];
    }
}

위 내용은 laravel8의 dingo 및 jwt 인증 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 jianshu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제