Laravel 5.3 API 認證 Authentication – Passport

什麼是 Passport ?

相信大家都有使用過 Facebook Login、Google Login … 等等 oAuth2 社群認證
在 Laravel 5.1 時 都是使用 dingo 這個套件來完成 oAuth Server 的認證

下一篇來講 dingo 的強大功能(多重API身份認證)

Laravel 5.3 提供了一個很棒的認證方法 – Passport

Passport 是一個由 Laravel 原生所提供的套件,當將套件引入後可以使用 migration 與 設置 provider 快速搭建整個 oAuth Server。

在 Laravel 5.3 中安裝 Passport

第1步驟:將套件加入專案中

於專案資料夾中執行

composer require laravel/passport

執行完畢後於 config/app.php 的 $providers 陣列中加入 Laravel\Passport\PassportServiceProvider::class

1.1 步驟:

  1. 執行 migrate
    <code class=" language-php">php artisan migrate</code>

    %e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%8812-06-59

  2. 執行 passport:install 加密
    <code class=" language-php">php artisan passport:install</code>

    %e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%8812-08-41

  3. 這個指令將會處理三件事情
    1. 產生 oauth2 加密金鑰
    2. 替你建立一個Personal access client
    3. 替你建立一個Password grant client

1.2 步驟:修改 User Class ,並且 use Laravel\Passport\HasApiTokens traits

1.3 步驟:在你的 app/Providers/AuthServiceProvider 文件中引入 use Laravel\Passport\Passport,接著在 boot() 方法中添加 OAuth2 路由方法 Passport::routes()

1.4 步驟:在 config/auth.php 中,將 guards 陣列中的 api driver 修改成 passport

<code class=" language-php"><span class="token string">'api'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span>
        <span class="token string">'driver'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token string">'passport'</span><span class="token punctuation">,</span>
        <span class="token string">'provider'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token string">'users'</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span></code>

第2步驟: 建立認證 Server 前端(需使用 Vue.js)

2.1 php artisan vendor:publish tag=passport-components

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%8812-51-08

2.2 將 Passport 套件中的 vue 寫入 resources/assets/js/app.js

2.3 php artisan make:auth

執行 php artisan make:auth 來增加 Auth:routes();

2.4 在 home.blade.php 中加入 gulp 編譯後的 html tag.

第3步驟: 使用者新增需要與應用程序的API交互的端口與return url.

3.1步驟  The passport:client Command

使用指令建立一個的 client-api 端口

<code class=" language-php">php artisan passport<span class="token punctuation">:</span>client

<a href="http://codingweb.tw/wp-content/uploads/2016/10/螢幕快照-2016-12-23-下午3.52.21.png"><img class="alignnone size-full wp-image-917" src="http://codingweb.tw/wp-content/uploads/2016/10/螢幕快照-2016-12-23-下午3.52.21.png" alt="%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%883-52-21" width="1051" height="335" /></a>
</code>

或著你喜歡使用圖形模式去完成它,登入你的server端會員以後 在你剛剛加入 vue 的模板那視圖下新增一個Oauth Clients

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%884-00-29

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%883-53-30

第4步驟: 建立 Client 端

4.1 步驟 新建一個 Client 端專案,並且於 routes/web.php 中加入根據你在 「3.1步驟」所建立的 redirect_url 及 client_id 進行配置

部署這個專案時請先 composer require guzzlehttp/guzzle 因為我們將會在 routes/web.php 中使用到

4.2 步驟 接著試著連結 http://Laravel53-passport-client.dev/redirect 你會發現被導到 http://Laravel53-passport-server.dev 進行認證

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%884-00-23

是的,因為我剛剛沒有在 AuthServiceProvider 中設定任何特殊權限,所以這裡也沒有說明要哪些資料
所以我們回到 Server 端 並在 AuthServiceProvider.php 配置權限

好的,試著再讓我們嘗試一次,在 client 端的 routes/web.php 帶 scope 參數存取特定資源

讓我們在連結一次 http://Laravel53-passport-client.dev/redirect

你將會得到回來的 access_token 及 token_type ,我們將使用這組 token 向 server 要求存取我們所需要的資源!

4.3 步驟 配置 Server 端 API 路由

我們試著不帶 access_token 去存取我們所要的資源,會發生什麼事情?(我們使用 Postman)

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%884-49-19

果不其然回傳了 unauthenticated, 那讓我們帶著 access_token 再試一次

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%885-12-32

成功了!接著我們修改 Server 端的 api.php 看指定特定資源時 passport 會不會將沒有該權限的 token 給擋下來

首先我們要先在 Kernel.php 中加入套件中的 middleware ,在 routeMiddleware 陣列中加入
‘scopes’ => \Laravel\Passport\Http\Middleware\CheckScopes::class,
‘scope’ => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,

scopes 代表的是必須完全與條件相符才可存取
scope 則代表任一個相同即可存取

當您測試後會發現,傳到需要 facebook_information 和 twitter_information 時,會傳回認證失敗的錯誤訊息!

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%885-44-56

而其他的我們將會通過認證並且取得資料!

*若是你在認證的途中導向時出現了要求提供使用者名稱及密碼,意思是你配置的 server 端資訊可能與 client 端不同,請確認好兩邊的資訊是否 match 
%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-23-%e4%b8%8b%e5%8d%884-08-32

感謝你的耐心,此篇文章的程式碼也有放上 Github 。

Laravel53-passport-server-tutorial: https://github.com/Maras0830/Laravel53-passport-server-tutorial

Laravel53-passport-client-tutorial: https://github.com/Maras0830/Laravel53-passport-client-tutorial

 

參考資料: Laravel News – Passport

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *