1. 程式人生 > 其它 >laravel8配置jwt並支援自動重新整理

laravel8配置jwt並支援自動重新整理

使用tymon/jwt-auth包(https://packagist.org/packages/tymon/jwt-auth)

1、安裝

composer require tymon/jwt-auth

2、釋出配置,執行以下命令以釋出包配置檔案:您現在應該有一個config/jwt.php檔案,允許您配置此包的基礎知識。

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

3、生成祕鑰

php artisan jwt:secret

這將.env使用類似的內容更新您的檔案

JWT_SECRET=foobar

這是將用於簽署您的令牌的金鑰。這究竟如何發生將取決於您選擇使用的演算法。

4、更新您的使用者模型

<?php

namespace App\Models;

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

class TestUser extends Authenticatable implements JWTSubject
{
    use Notifiable;

    public $timestamps = false;

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        // TODO: Implement getJWTIdentifier() method.
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

  

並新建test_user表

CREATE TABLE `test_users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `phone` char(11) COLLATE utf8mb4_general_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `sex` tinyint NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

5、配置身份驗證保護

注意:這僅在您使用 Laravel 5.2 及更高版本時有效。

在該config/auth.php檔案中,您需要進行一些更改以配置 Laravel 以使用jwt防護來支援您的應用程式身份驗證。

對檔案進行以下更改:

'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],

...

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

這裡我們告訴api守衛使用jwt驅動程式,我們將api守衛設定為預設值。

我們現在可以使用 Laravel 內建的 Auth 系統,由 jwt-auth 完成幕後工作!

6、新增一些路由,使用了auth.jwt自定義的中介軟體

Route::post('login', [\App\Http\Controllers\TestUserController::class, 'login']);
Route::post('register', [\App\Http\Controllers\TestUserController::class, 'register']);
Route::group(['middleware' => ['auth.jwt']], function () {
    Route::get('logout', [\App\Http\Controllers\TestUserController::class, 'logout']);
    Route::get('user', [\App\Http\Controllers\TestUserController::class, 'getAuthUser']);
    Route::get('refresh', [\App\Http\Controllers\TestUserController::class, 'refresh']);
});

7、建立控制器

php artisan make:controller TestUserController

8、新增以下內容

<?php

namespace App\Http\Controllers;

use App\Http\Response\BizFailResponse;
use App\Http\Response\BizSuccessResponse;
use App\Library\DataChecker;
use App\Models\TestUser;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\JWTAuth;

class TestUserController
{

    public function register(Request $request)
    {
        $params = $request->input();
        DataChecker::requireExpectParamIsNonEmptyStr($params, 'phone');
        DataChecker::requireExpectParamIsNonEmptyStr($params, 'sex');
        DataChecker::requireExpectParamIsNonEmptyStr($params, 'password');
        $userInfo = TestUser::query()->where('phone', $params['phone'])->get()->toArray();
        if (!empty($userInfo)){
            return BizFailResponse::makeWithMsg("該賬號{$params['phone']}已被註冊");
        }
        $user = new TestUser();
        $user->phone = $params['phone'];
        $user->sex = $params['sex'];
        $user->password = bcrypt($params['password']);
        $user->save();
        return BizSuccessResponse::makeWithData($user);
    }

    public function login(Request $request)
    {
        $input = $request->only('phone', 'password');
        $jwt_token = null;
        if (!$jwt_token = auth()->attempt($input)) {
            return BizFailResponse::makeWithMsg('賬號或者密碼錯誤');
        }
        return BizSuccessResponse::makeWithData(['token'=>$jwt_token]);
    }

    public function logout(Request $request)
    {
        try {
            auth()->invalidate();
            return BizSuccessResponse::makeWithMsg('登出成功');
        } catch (JWTException $exception) {
            return BizFailResponse::makeWithMsg('登出失敗');
        }
    }

    public function refresh(){
        return BizSuccessResponse::makeWithData(['token'=>auth()->refresh()]);
    }

    public function getAuthUser(Request $request)
    {
        $user = auth()->user();

        return response()->json(['user' => $user]);
    }
}

9、新建中介軟體,支援token校驗和過期自動重新整理

php artisan make:middleware AuthJwtTokend  

  程式碼如下:

<?php

namespace App\Http\Middleware;

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

/**
 * 驗證token,並且過期自動重新整理
 * Class AuthJwtToken
 * @package App\Http\Middleware
 */
class AuthJwtToken extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {

        $this->checkForToken($request);
        try {
            if ($this->auth->parseToken()->authenticate()){
                return $next($request);
            }
            throw new UnauthorizedHttpException('jwt-auth', '該使用者未登入');
        }catch (TokenExpiredException $e){
            try {
                $token = $this->auth->refresh();
                Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
                // 在響應頭中返回新的 token
                return $this->setAuthenticationHeader($next($request), $token);
            }catch (JWTException $e) {
                throw new UnauthorizedHttpException('jwt-auth', $e->getMessage());
            }
        }
    }
}

10、註冊自定義中介軟體

App\Http\Kernel中$routeMiddleware新增
// 自定義中介軟體
'auth.jwt' => AuthJwtToken::class

11、訪問註冊、登入、登出、獲取使用者資訊等介面