Laravel 的 API 認證系統(tǒng) Passport 三部曲(二、passport的具體使用)

參考鏈接

Laravel 的 API 認證系統(tǒng) Passport 三部曲(一、passport安裝+配置)

Laravel 的 API 認證系統(tǒng) Passport

引言

  1. 在使用前要先了解Auth2.0的使用方式和原理Laravel 的用戶認證系統(tǒng)
  2. passport是專門做api令牌授權的工具,這里有個問題是他不像auth一樣可以定義多個guard來區(qū)分不同平臺走不同的auth認證模塊,他默認只走guard=api這個api認證模塊。

密碼授權令牌的獲取

  • 請求令牌
    創(chuàng)建密碼授權的客戶端后,就可以通過向用戶的電子郵件地址和密碼向 /oauth/token 路由發(fā)出 POST 請求來獲取訪問令牌。而該路由已經(jīng)由 Passport::routes 方法注冊,因此不需要手動定義它。如果請求成功,會在服務端返回的 JSON 響應中收到一個 access_token 和 refresh_token:

    $http = new GuzzleHttp\Client;
    
    $response = $http->post('http://your-app.com/oauth/token', [
        'form_params' => [
            'grant_type' => 'password',
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
            'username' => 'taylor@laravel.com',
            'password' => 'my-password',
            'scope' => '',
        ],
    ]);
    
    return json_decode((string) $response->getBody(), true);
    

私人訪問令牌

在你的應用程序發(fā)布個人訪問令牌之前,你需要在 passport:client 命令后帶上 --personal 參數(shù)來創(chuàng)建對應的客戶端。如果你已經(jīng)運行了 passport:install 命令,則無需再運行此命令:

php artisan passport:client --personal

創(chuàng)建個人訪問客戶端后,你可以使用 User 模型實例上的 createToken 方法來為給定用戶發(fā)布令牌。
createToken 方法接受令牌的名稱作為其第一個參數(shù)和可選的 作用域 數(shù)組作為其第二個參數(shù):

$user = App\User::find(1);

// Creating a token without scopes...
$token = $user->createToken('Token Name')->accessToken;

// Creating a token with scopes...
$token = $user->createToken('My Token', ['place-orders'])->accessToken;

注意: 由于passport默認只可以走一個guard認證,當多平臺的時候,可以使用auth2.0來輔助操作,首先使用Auth2.0驗證該平臺對應的guard(當然,驅(qū)動使用session))下其賬號密碼是否正確,驗證通過之后再獲取該用戶實例并給予私人訪問令牌,這樣就做到了不同平臺的令牌生成)

驗證令牌

  • 通過中間件

    Passport 包含一個 驗證保護機制 可以驗證請求中傳入的訪問令牌。配置 api 的看守器使用 passport 驅(qū)動程序后,只需要在需要有效訪問令牌的任何路由上指定 auth:api 中間件:

    Route::get('/user', function () {
        //
    })->middleware('auth:api');
    
  • 我們實現(xiàn)方式

    由于passport只可以走api一個guard驗證,也就是只可以走一個用戶授權表,這里我們多平臺多登陸授權表則只用上面的驗證登陸肯定就不對了,如上所說我們結合auth2.0來進行分平臺進行驗證。

    1. 首先創(chuàng)建一個AuthApi中間鍵
    2. 在/app/Http/Kernel.php中注冊AuthApi中間鍵

    eg:

    public function handle($request, Closure $next, $guard = null)
    {
        if (empty(Auth::guard($guard)->user())) {
            return response()->json(["message" => "Unauthenticated."], 401);
        }
    
        return $next($request);
    }
    

    protected $routeMiddleware = [
    'apiAuth' => ApiAuth::class,
    ......
    ];

    1. 使用的時候比如要使用guard=home的驗證令牌,則中間件為“apiAuth:home”即可

注銷登錄、定期檢查過期token,銷毀舊的token

  • 注銷登錄

    eg:

    /**
     * 登出程序操作.
     *
     * @return \Illuminate\Http\Response
     */
    public function logout()
    {
        $user = $this->guard()->user();
        if (empty($user)) {
            return $this->sendError('暫未登錄', ['暫未登錄'], 403);
        }
    
        // 獲取當前登陸用戶的access_token的id
        $accessToken = $user->access_token;
    
        // 找到這條access_token并且將其刪除
        $token = Token::find($accessToken);
        if (empty($token)) {
            return $this->sendError('暫無有效令牌', ['暫無有效令牌'], 403);
        }
    
        if (!empty($token->delete())) {
            return $this->sendResponse([], '退出成功!');
        } else {
            return $this->sendError('退出失敗', ['退出失敗'], 500);
        }
    }
    
  • 定期檢查過期token(官方文檔沒給,個人做的優(yōu)化)

    • 創(chuàng)建token生成事件的監(jiān)聽器來處理該用戶當前客戶端下的所有失效的token

      在“/app/Providers/EventServiceProvider.php”中的“$listen”數(shù)組中添加

      // 生成token,檢查失效的進行刪除
      'Laravel\Passport\Events\AccessTokenCreated' => [
          'App\Listeners\RevokeOldTokens',
      ],
      

      終端執(zhí)行:

      php artisan event:generate
      

      提示:"Events and listeners generated successfully!"代表創(chuàng)建成功了

    • 執(zhí)行刪除失效token操作

      在 'App\Listeners\RevokeOldTokens'的handle方法中執(zhí)行刪除失效token操作

      Token::where('id', '!=', $event->tokenId)
          ->where('user_id', $event->userId)
          ->where('client_id', $event->clientId)
          ->where('expires_at', '<', Carbon::now())
          ->orWhere('revoked', true)
          ->delete();
      
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容