「 原創 」Laravel 5.8 API 開發實戰(四)

安裝 Passport

用 composer 安裝 passport,運行 composer require laravel/passport

「 原創 」Laravel 5.8 API 開發實戰(四)

安裝passport

安裝完成後,passport 服務提供器會自動使用框架註冊自己的數據庫遷移目錄,只需要運行 php artisan migrate 即可。

當然了,如果不想使用 passport 的默認遷移,可以在 AppServiceProvider 的 register 方法中調用忽略遷移的方法 Passport::ignoreMigrations

「 原創 」Laravel 5.8 API 開發實戰(四)

註冊數據表


生成密鑰

運行 php artisan passport:install,該命令會生成安全訪問令牌時所需要的加密密鑰

「 原創 」Laravel 5.8 API 開發實戰(四)

生成密鑰


更新模型

上述命令執行完成,生成密鑰後,需要將 Trait 添加到 APP/User 模型中,提供一些需要的輔助函數。

<code> 'datetime',
    ];
    
    /**
     * 通過用戶名/手機號碼找到對應的用戶信息
     *
     * @param string $username
     * @return User
     */
    public function findForPassport($username) {
        return $this->orWhere('username', $username)->orWhere('email', $username)->orWhere('phone', $username)->first();
    }
}/<code>


服務提供器(Provider)

在 app/Providers 目錄下,修改 AuthServiceProviders.php 中的 boot 方法,調用 Passport::routes 函數,這個函數會註冊一些必須的路由(發出 / 撤銷 訪問令牌(客戶端 / 個人)等)

<code> 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}/<code>


授權看守器(Guard)

修改配置文件 config/auth.php 中 api 的授權看守器 gurads,將 driver 選項改為 passport。

<code>'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
]/<code>


token 有效期

Passport 頒發的訪問令牌,默認是一年有效的,如果想自定義訪問令牌的有效期,可使用 tokensExpireIn 及 refreshTokensExpireIn 方法去設置(app/Providers/AuthServiceProvider.php)

<code>public function boot() {
    $this->registerPolicies();
    Passport::routes();
    Passport::tokensExpireIn(now()->addDays(10));
    Passport::refreshTokensExpireIn(now()->addDays(30));
}/<code>


部署 passport

運行:php artisan passport:keys (該命令會生成 Passport 生成訪問令牌所需的密鑰)

「 原創 」Laravel 5.8 API 開發實戰(四)



密碼授權令牌

OAuth2 密碼授權機制,可以非常方便自己的客戶端通過手機號碼(或郵箱)+ 密碼的形式,進行授權,獲取訪問令牌,無需遍歷整個OAuth2 整個授權流程。

密碼授權客戶端

如果此前安裝 passport 時,執行過 php artisan passport:install 命令的,將無需執行下面的命令,因為該指令已經生產兩條數據,即生成了對應的客戶端,具體可以查看 oauth_client 數據表。

若是未執行上述命令,可執行:php artisan passport:client --password ,對應的輸入想要的用戶名即可。

「 原創 」Laravel 5.8 API 開發實戰(四)

「 原創 」Laravel 5.8 API 開發實戰(四)

生成密碼授權客戶端


請求令牌

客戶端創建後,就可以通過電子郵件地址與密碼向 /oauth/token 發 POST 請求了,需要注意的是,該路由已經通過 Passport::routes 註冊過,無需另外手動註冊,如果請求成功,則會返回如下所示的 JSON 對象,包含 token_type(類型),expires_in(過期時間),access_token 及 refresh_token

<code>{
    "token_type": "Bearer",
    "expires_in": 1296000,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjQxOTI0MWIyMTYyMDkwMGEzMjBhZjVjZWUxNjgzYzkwZTE2Y2NiOTcyMzE3MzU4NzRiNmNkNTgxNTZjNzY3YzhlNjJiMjNlNWJkYzdjZDM1In0.eyJhdWQiOiI0IiwianRpIjoiNDE5MjQxYjIxNjIwOTAwYTMyMGFmNWNlZTE2ODNjOTBlMTZjY2I5NzIzMTczNTg3NGI2Y2Q1ODE1NmM3NjdjOGU2MmIyM2U1YmRjN2NkMzUiLCJpYXQiOjE1NTY1Mjk4NjUsIm5iZiI6MTU1NjUyOTg2NSwiZXhwIjoxNTU3ODI1ODY1LCJzdWIiOiIxIiwic2NvcGVzIjpbIioiXX0.ng5lmGdiwRGOxYRkW7R0Ox7VSb5pWIlRaxMbWikbIP0GyEhL4ABJjvA4LVNb8k0molnghbTrUxr8V9yNTI-dVzt8iNzEXEvQ2N_jBWL-96M85V_QybDq0nHMU5vdPqxbbcjZNoAz53GD-QQPpwlaT6X1IpjjkAcXKwY_SBywGG3LSeaYEVO9GhcSjEG27BDFdYHHWD6C-gJwt1IsZ5ggfgxsC3vakfay3aQbRaoQycvk_lYzJA-xwcqJodOx6OkeSPm64Whq2njbyQ4YRUsvLo6DbWm5bZ6vVd4INTetwJErjMMn6XMcHp3Oont6UetuMeg_VdhPcnI58ew1DjbDAlpBk-B5z-MAMxPrhQYLFgsqOU8YdSQD4ddTD7OW9NUyjvNqcQAvoJIYfUCsGw3hTG9VXG7TyJQJQ_I5oq7_5gHLcuaHJn5Pzfq47Tql88UnoQZKSw4FcfEDP7uXNXAdg5edc4wnog8LMeIa6WqYXfnjy5rIjLnhJcq-6Ot4KIOVjNL3teDLCe9A7fv7tdLSJiCf4Pz-jEjRS_Z0pdHdwyFihUWcl578JKHAHlj4B0CY9zXSmTdNeY-LofKP1vaFX8Ct6sQsYOJB-O3oOqfxeVHNRYD6liPWnLcFmyBFR9qV-XpSCR-PnxwBUJ9s0v_tCpHfwDMO6T8jf72OxZ-H8IA",
    "refresh_token": "def502005aa00689b542002eb9f23e83351ffeb309d6b804023b533804d36652ad1a8458fe7bf14e25043b28c2b842938dd6b056202bddd568d6bdccdd000d913c76cfd281b7a1df56675c4f04f56f4b63b68011d13a5e363bf64de44931faabf22b672f63cbe215f664f52c1830d217f39c3688adaec49f97f95652777e9f4bab5184c6d51c0ae93ad0f3b64c01c0b22bc67c577c6fa9a4247a8865a6eae9b3f37d1c496e9274e4ae6bb01e830461bde27e562f3a31f420bd34cb1d30456336c85cc40dcf8290b74d7661ade84efe81cfa3fc623c78bb3f6ca385dcc60278e6be10c9127206ca55144f7d419e87b89e19d48e159b790d66d3d65860dacc87f7b9806e770eff8436c87c18cdfa75a2e4e7cc1430876b78f647608189214fc2daa465758e6c51909a08bd1aa868978821144b74f65a124d84195d1b0cbafdbca9c664ac082b1f2bd14aa728d740a7b17073413db6af179940d79de0b43ada6f01ee56795a"
}/<code>
「 原創 」Laravel 5.8 API 開發實戰(四)

POST請求成功後的返回

請求令牌過程中有幾個需要注意的點:

1 - 採用 postman 之類的工具請求時,用 application/x-www-form-urlencode,即 form data 形式提交,否則會返回 unsupported_grant_type 的錯誤。

2 - 如果出現 invalid_credentials 錯誤,修改提交參數,默認未修改的情況下,username 值使用電子郵件地址,即類似以 [email protected] 作為 username 的值 ( 當然,可以自定義用戶名字段, 查看上面所述中《更新模型》這一塊的內容 )

3 - 該方式,默認情況下,發放的訪問令牌是長期有效的,如果需要修正時間,請查看 《Laravel 5.8 API 開發實戰(三)》

「 原創 」Laravel 5.8 API 開發實戰(四)

unsupported_grant_type 錯誤

「 原創 」Laravel 5.8 API 開發實戰(四)

invalid_credentials 錯誤


請求作用域

使用密碼授權機制時,請求參數中若攜帶了 scope 參數,且值為 * 的話,令牌實例中的 can 方法將一直都返回 true 的狀態;這種作用域的授權只能分配給使用 password 授權的令牌。

頒發訪問令牌

使用授權碼時,客戶端的應用程序會將用戶重定向我們的授權服務器,授權服務器返回信息進行詢問用戶,是批准還是拒絕該客戶端訪問授權令牌(如果對於OAuth的授權流程不清楚的話,可以查看阮一峰《關於 OAuth2.0 的理解》的日誌)

管理客戶端

很顯然,為了方便測試 OAuth2.0 的功能,我們需要生成一個 [ 客戶端 ] 來註冊自己的應用程序,完成整個授權流程, php artisan passport:client,該命令會創建一個客戶端(第三方或用戶是無法使用 client 命令的,此處是為了方便測試)。

「 原創 」Laravel 5.8 API 開發實戰(四)

如上圖所示,為這個客戶端分配了 user 表中 id = 1 的用戶;若該 user 表為空的話,可以運行如下命令完成用戶創建。

<code>php artisan tinker
App\User::create(['name' => 'makeit', 'email' => '[email protected]', 'password' => bcrypt('123456')]);/<code> 
「 原創 」Laravel 5.8 API 開發實戰(四)

雖然用戶或者第三方無法使用 client 命令進行客戶端創建,但是 Laravel 提供了一系列的接口,我們也就不用費時費事的去編寫控制器來操作了,當然,要管理這些客戶端,還是需要添加,刪除等相關的管理頁面的;此處我們為了方便測試,就不進行頁面展示了,我們只用 postman,resetlet 等工具來進行接口測試,但是這些 API 由 web 與 auth 兩個中間件的保護,正常情況下只能從應用程序內部進行調用,外部是不允許調用的,所以需要進行一些準備工作的,本篇就說一下跨域問題的解決,其它的準備工作就先不贅述了。

CORS 跨域

composer require barryvdh/laravel-cors,執行該命令,安裝 laravel-cors

「 原創 」Laravel 5.8 API 開發實戰(四)

安裝 laravel-cors


config/app.php 文件內的 alials 中,添加如下內容,註冊相應的服務:

<code>'CROS' => Barryvdh\Cors\HandleCors::class/<code>

修改 app/Http/Kernel.php 文件,此處可分全局和局部使用兩種方式,全局使用則將該服務添加到 $middleware 內容中,局部的則添加至 $middlewareGroups 中的 web / api 中都可以。

<code>/<code>
「 原創 」Laravel 5.8 API 開發實戰(四)

全局使用

「 原創 」Laravel 5.8 API 開發實戰(四)

局部使用

執行 php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider" 發佈 cors 的配置。

「 原創 」Laravel 5.8 API 開發實戰(四)

發佈配置後,在 config 目錄下生成了 cors.php 配置文件,可以在 allowedHeaders 自定義 header,比如 Content-Type,X-Requested-With。白名單或者確定可訪問的域名,在 allowedOrigins 添加即可,自行配置。

「 原創 」Laravel 5.8 API 開發實戰(四)

至此,oAuth 2.0 密碼授權令牌的實現就完成了,另外還講述了相關的客戶端管理及其跨域的一些問題,三四篇下來,基本上 API 開發的起步工作算是完成了,從最初《Laravel 5.8 API 開發實戰(一)》跑通無授權的接口,至《Laravel 5.8 API 開發實戰(二)》實現 jwt-auth 的認證,再到《Laravel 5.8 API 開發實戰(三)》實現無感刷新 token,再到當前實現 oAuth 2.0 密碼授權,總結整理了 API 開發的前期準備工作,後續將結合開發實際,說說具體的功能點,比如採用 RabbitMQ,結合 QQ 郵箱,實現註冊的郵件的異步發送,加快響應速度之類的 ......


分享到:


相關文章: