OAuth2 認證套件

使用套件

套件名稱:lucadegasperi/oauth2-server-laravel

套件版本:5.0.3

名詞解釋

名詞 描述
Access token 存取標記,用於存取受保護資源的標記
Authorization code 授權碼,使用者授權 Client 的中介標記,Client 可以透過此授權碼去取得 Access token
Authorization server 授權伺服器,使用者授權 Client 後,用於發送 Access token 的伺服器
Client 被授權客戶,存取屬於使用者的受保護資源的應用程式(Application), 像是 Server、手機或其他裝置
Grant 授權方法,存取 Access token 的方法
Resource server 資源伺服器,屬於使用者的受保護資源(像是文章、照片、個人隱私資料…等等)
Scope 資源存取範圍,Access token 允許存取的權限

ref: lucadegasperi/oauth2-server-laravel - Terminology

安裝

使用 composer 安裝套件

composer.json 加入 "lucadegasperi/oauth2-server-laravel": "5.0.*" 並執行 composer update 安裝套件

/*composer.json*/
"require": {
  "lucadegasperi/oauth2-server-laravel": "5.0.*"
}
$ composer update

設定套件

開啟config/app.php檔案,並將系列套件資訊加入 providersaliases

'providers' => [
    LucaDegasperi\OAuth2Server\Storage\FluentStorageServiceProvider::class,
    LucaDegasperi\OAuth2Server\OAuth2ServerServiceProvider::class,
],
'aliases'=>[
    'Authorizer' => LucaDegasperi\OAuth2Server\Facades\Authorizer::class,
]

設定 middleware

開啟 app/Http/Kernel.php,將系列設定加入 $middleware 與 $routeMiddleware 中

並將原本在 $middleware 的 \App\Http\Middleware\VerifyCsrfToken::class 移至 $routeMiddleware,並命名為 csrf

注意,原本 Laravel 會針對每個非 Get 的 Request 做 CSRF 的過濾,因為 OAuth 已經取得授權 Access token,不需要 CSRF 驗證,所以如果你需要做 CSRF 驗證的話,您可以在 Route 加入 csrf 的 middleware 去做驗證

<?php

class Kernel extends HttpKernel
{
    protected $middleware = [
        \LucaDegasperi\OAuth2Server\Middleware\OAuthExceptionHandlerMiddleware::class
    ];

    protected $routeMiddleware = [
        // CSRF
        'csrf' => \App\Http\Middleware\VerifyCsrfToken::class,
        // OAuth2
        'oauth' => \LucaDegasperi\OAuth2Server\Middleware\OAuthMiddleware::class,
        'oauth-user' => \LucaDegasperi\OAuth2Server\Middleware\OAuthUserOwnerMiddleware::class,
        'oauth-client' => \LucaDegasperi\OAuth2Server\Middleware\OAuthClientOwnerMiddleware::class,
        'check-authorization-params' => \LucaDegasperi\OAuth2Server\Middleware\CheckAuthCodeRequestMiddleware::class
    ];
}

產生套件設定及 Migration

執行 php artisan vendor:publish 複製套件的 migrationconfig/oauth.php 設定檔到你應用程式的目錄,並執行 migration 建立 OAuth2 需要的資料表

$ php artisan vendor:publish
$ php artisan migrate

設定檔名詞解釋

參數名稱 說明 資料類型 預設值
grant_types 授權類型設定 Array
token_type token 類型 String League\OAuth2\Server\ TokenType\Bearer
state_param 狀態參數,如果為 true 的話,在請求 Access token 時候則必須帶入 &state=隨機字串,在透過授權後 Authorization server 會回覆相同的 state 字串 Boolean false
scope_param 存取權限參數,若為 true,則在每一次的 Request 都需要帶入該資源的存取參數 Boolean false
scope_delimiter 存取權限區隔字串,在不同的存取權限使用什麼字元去區隔(scope1,scope2) String ,
default_scope 預設存取權限 String null
access_token_ttl Access token 存活時間(單位:秒) Integer 3600
limit_clients_to_grants 是否限制 Client 允許使用的 Grant Type,可以在 oauth_client_grants 資料表設定 Boolean false
limit_clients_to_scopes 限制 Client 允許的 Scope,可以在 oauth_client_scopes 資料表設定 Boolean false
limit_scopes_to_grants 限制 Scope 允許在哪個 Grant Type 存取,可以在 oauth_grant_scopes 資料表設定 Boolean false
http_headers_only 是否只使用 Header 做 Access token 的檢查 Boolean false

OAuth2 Access token 取得的方式

OAuth2 總共有下列 4 種 Access token 取得的方式

Access token 取得方式 說明
Client Credentials 純 Client 資料身份驗證,僅需要 client_id 與 client_secret 正確即可取得 Access token
Password 資源擁有者須登入帳號密碼,確認可以讓 Client 取得 Access token
Auth Code Grant 資源擁有者授權 Client 可以存取指定 Scope 的資源並給予授權碼,Client 透過此授權碼取得該 Scope 的 Access token
Refresh Token Grant 授權 Client 在取得 Access token 時也一併取得 Refresh token,在 Access token 過期時,Client 可以用此 Refresh token 取得新的相同權限的 Access token

設定存取 Access token 路由

不管是何種 OAuth2 Access token 取得的方式,都須透過相同的路由去取得 Access token,OAuth2 會根據每個取得方式參數的不同做不一樣的驗證,所以我們只有設定下列路由即可

Route::post('oauth/access_token', function() {
    return Response::json(Authorizer::issueAccessToken());
});

設定 client_id 與 client_secret

每一個 Client 應用程式都會有自己的 client_idclient_secret,你可以自己設定你要核發給 Client 授權 client_id 與 client_secret 的頁面,並將資料分別存放在 oauth_clients 資料表的 id 與 secret 欄位中

Schema::create('oauth_clients', function (BluePrint $table) {
    $table->string('id', 40)->primary();    // client_id
    $table->string('secret', 40);           // client_secret
    $table->string('name');                 // Client 名稱
    $table->timestamps();
    $table->unique(['id', 'secret']);
});

Client 資料新增完成之後,之後 Client 可以透過這個 client_id 與 client_secret 去要求取得 Access token,我們這裡以新增 id 為 KeKyun 及 secret 為 KeJyunSecret 作為之後的範例

INSERT INTO "oauth_clients" ("id", "secret", "name", "created_at", "updated_at")
VALUES ('KeJyun', 'KeJyunSecret', 'KeJyun Client', now(), now());

client_id 與 client_secret 欄位長度皆為 40,在產生資料時請自行產生長度 40 的亂數字串,這裡僅用於示範使用非亂數的 client_id 與 client_secret

參考資料

KeJyun 最新新書推薦
- Laravel 5 for beginner 新手道場:優雅運用框架快速開發 PHP 網站
- Laravel框架开发详解:从零基础到运用框架快速开发PHP网站

Laravel 是 PHP 的框架(Framework),提供了很多開發網站或 API 所需的工具及環境,經過簡單的設定就可以完成資料的處理及顯示,使開發者可以很優雅且快速的開發出各個不同的產品。本書適合有 PHP 基礎的人,但不知道要怎麼選擇框架,或者不用框架的人也能夠明白它的好處。

雖然 WordPress 也能夠架站,但如果有客製化需求,要開發各式各樣的網站,或提供 App 使用的 API,如此一來你只能選擇用框架,而 Laravel 是目前最受歡迎的。

本書將解說為什麼要使用框架,以及理解框架的優缺點後,要怎麼選擇框架,並用框架快速建構一個網站。除非必要,否則書中會避免專業技術用語,盡量使用最生活化易懂的例子及語氣,讓大家更容易進入 Laravel 的世界。

Laravel 5 for beginner 新手道場:優雅運用框架快速開發 PHP 網站

購書連結

Laravel框架开发详解:从零基础到运用框架快速开发PHP网站

購書連結

comments powered by Disqus