透過 Passport 實現 API 請求認證(移動端的密碼授權令牌)

Jouzeyu發表於2020-02-16

前言

大家好,新年快樂。這篇主要講透過 Passport 實現 API 請求認證,選擇 Passport 的理由主要是官方推薦以及好像 Dingo API 不太支援Laravel6.0版本,接下來就常用的兩個需求介紹 Passport 的使用。

安裝並初始化

  1. 首先透過 Composer 安裝 Passport 擴充套件包:
    composer require laravel/passport
  2. 執行資料庫遷移命令建立 OAuth 相關資料表
    php artisan migrate
  3. 接著執行下列命令
    php artisan passport:install
  4. 在對應模型類中使用 Laravel\Passport\HasApiTokens Trait,比如 User 模型:
    ...
    use Laravel\Passport\HasApiTokens;
    class User extends Authenticatable
    {
     use HasApiTokens, Notifiable;
     ...
  5. 在 AuthServiceProvider 的 boot 方法中註冊 API 認證相關路由:
    // 引入名稱空間
    use Laravel\Passport\Passport;
    ...
    public function boot()
    {
     ...
     //註冊 API 認證路由
     Passport::routes();
    }
  6. 修改配置檔案 config/auth.php,將 API 認證驅動由 token 修改為 passport:
    'guards' => [
     ...
     'api' => [
         'driver' => 'passport',//這裡
         'provider' => 'users',
     ],
    ],

獲取密碼授權令牌

  1. 建立客戶端

    php artisan passport:client --password

    我們會得到類似下面的內容:

    Client_ID:3
    Client_Secret:2JPrCvRyoJ14f0OqCe6nnQZNDfPLNNPY7TcfDnco
  2. 將敏感資訊放進.env檔案

    CLIENT_ID=3
    CLIENT_SECRET=2JPrCvRyoJ14f0OqCe6nnQZNDfPLNNPY7TcfDnco
  3. 在 config/services.php 中新增配置項:

    'blog' => [
     'appid' => env('CLIENT_ID'),
     'secret' => env('CLIENT_SECRET'),
    ]
  4. 在相應的控制器中寫入登入驗證並返回token值的方法:

    <?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use GuzzleHttp\Client;
    class IndexController extends Controller
    {
     public function login(Request $request)
     {
         $http = new Client();
         // 傳送相關欄位到後端應用獲取授權令牌,網址為我的測試網址
         $response = $http->post('http://test.test/oauth/token', [
             'form_params' => [
                 'grant_type' => 'password',
                 'client_id' => config('services.blog.appid'),
                 'client_secret' => config('services.blog.secret'),
                 'username' => $request->input('email'),  // 這裡傳遞的是郵箱
                 'password' => $request->input('password'), // 傳遞密碼資訊
                 'scope' => '*'
             ],
         ]);
    
         return response($response->getBody());
     }
    }

    這樣當使用者訪問這個方法並傳入正確的登入郵箱及密碼的時候就能返回相應的token值,示例如下圖:

透過 Passport 實現 API 請求認證(移動端的密碼授權令牌)

其中access_token就是我們想要的token了。

重新整理令牌

如何重新整理令牌?通常情況下,我習慣將置換令牌與重新整理令牌放在一起,所以重新封裝login方法:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use GuzzleHttp\Client;
class IndexController extends Controller
{
    public function login(Request $request)
    {
        $http = new Client();
        //判斷grant_type型別
        if($request->input('type')=="refresh_token"){
            $response = $http->post('http://blog.test/oauth/token', [
                'form_params' => [
                    'grant_type' => 'refresh_token',
                    'refresh_token' =>  $request->input('token'),
                    'client_id' => config('services.blog.appid'),
                    'client_secret' => config('services.blog.secret'),
                    'scope' => '*',
                ],
            ]);
        }else{
          // 傳送相關欄位到後端應用獲取授權令牌,網址為我的測試網址
            $response = $http->post('http://test.test/oauth/token', [
                'form_params' => [
                    'grant_type' => 'password',
                    'client_id' => config('services.blog.appid'),
                    'client_secret' => config('services.blog.secret'),
                    'username' => $request->input('email'),  // 這裡傳遞的是郵箱
                    'password' => $request->input('password'), // 傳遞密碼資訊
                    'scope' => '*'
                ],
            ]);
        }

        return response($response->getBody());
    }
}

引數問題:當置換令牌時需要type、email、password,當重新整理令牌時需要type、access_token值。

當然這只是一種方案,僅供參考:smile:

本作品採用《CC 協議》,轉載必須註明作者和本文連結
空舟湖上~      ——Jouzeyu

相關文章