概要
- Laravel Passportを導入してちょっと使ってみた時のメモ
導入方法
-
下記コマンドを実行してライブラリそのものをインストールする。
$ composer require laravel/passport
-
下記コマンドを実行してマイグレーションを行う。
$ php artisan migrate
-
下記コマンドを実行してPassportをインストールする。(トークンを作成するための暗号化キーとPersonal access clientとPassword grant clientが作成されるらしい。)
$ php artisan passport:install
-
上記コマンドで発行された各種情報はDBのoauth_clientsテーブルに自動で格納される。
-
use Laravel\Passport\HasApiTokens;
の記載をApp/Models/User.php
に記載する。App/Models/User.phpuse Laravel\Passport\HasApiTokens; class User extends Authenticatable { use HasApiTokens; use HasFactory; use Notifiable; }
-
app/Providers/AuthServiceProvider.php
に下記の様に記載する。app/Providers/AuthServiceProvider.phpuse Laravel\Passport\Passport; // 省略 /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); if (! $this->app->routesAreCached()) { Passport::routes(); } }
-
config/auth.php
のguardsのapiのdriverをpassportに変更する。(apiの記載がない場合は記載する。)config/auth.php'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
-
config
直下を修正したので下記コマンドを実行してconfigのキャッシュクリアを行う。$ php artisan config:clear
-
下記コマンドを実行してUsersテーブルにデータを格納するシーダーを作成する。
$ php artisan make:seed UserSeeder
-
UserSeederファイルを下記の様に記載する。
databases/seeders/UserSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; class UserSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('users')->insert([ 'id' => 1, 'name' => 'test_user', 'email' => 'test@example.com', 'password' => Hash::make('p@ssw0rd'), ]); } }
-
DatabasesSeederファイルを下記の様に記載する。
databases/seeders/DatabaseSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Database\Seeders\UserSeeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call([ UserSeeder::class, ]); } }
-
下記コマンドを実行してseederを流す。
$ php artisan db:seed
-
アクセストークン取得後に実行テストするための処理を準備する。
routes/api.php
を開き、下記の内容を記載する。routes/api.phpRoute::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); });
使ってみる(Password Grant)
-
本方法はOAuth2では推奨されていない。しかしながら簡単でわかりやすいので、まずはPassword Grantというものを使ってトークン取得してみようと思う。
- 推奨されているGrant Type → https://oauth2.thephpleague.com/authorization-server/which-grant/
-
リクエストを送ることのできるツール(Postmanやthunder client)を用いて下記のリクエストを送る。
- リクエストの詳細
項目 値 備考 リクエスト送信URL /oauth/token 環境に応じて http://localhost:ポート番号
やhttp://127.0.0.1/oauth/token
として指定する。HTTPメソッド POST - POSTする値の情報(BodyのFormとして下記の値を送信する。)
項目 値 備考 grant_type password Password Grantを使う指定 client_id 2 $ php artisan passport:install
を実行した時に
oauth_clientsテーブルに格納された
nameカラムの値が「Laravel Password Grant Client」のレコードの
idカラムの値client_secret mPzZA8moXEe7iPzflQQWWjjsL6Lh3gC2hhArACyP $ php artisan passport:install
を実行した時に
oauth_clientsテーブルに格納された
nameカラムの値が「Laravel Password Grant Client」のレコードの
secretカラムの値
※左に記載されている値は皆さんのものとは異なりますusername text@example.com seederで登録したユーザーのメールアドレス password p@ssword seederで登録したユーザーのパスワード scope 何も入力しない -
筆者は下記の様な情報でリクエストを送った。
-
下記のような値が帰ってきた。認証が通り、アクセストークンとリフレッシュトークンが返された。(今回はテスト用に起動したアプリケーションで実施しているため戻り値を公開しているが、本来はあまり見せないほうが良い。)
{ "token_type": "Bearer", "expires_in": 31536000, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGci・・・", "refresh_token": "def50200a6be2104b700f49020130a・・・" }
-
帰ってきた値の
access_token
を用いてリクエストを送ってみる。リクエストを送ることのできるツール(Postmanやthunder client)を用いて下記のリクエストを送る。- リクエストの詳細
項目 値 備考 リクエスト送信URL /api/user 環境に応じて http://localhost:ポート番号
やhttp://127.0.0.1/oauth/token
として指定する。HTTPメソッド GET - POSTする値の情報(AuthのOAuth 2に下記の項目を追加して送信する。)
項目 値 備考 Access Token eyJ0eXAiOiJKV1QiLCJhbGci・・・ 先のリクエストで戻ってきたaccess_tokenの値をすべてコピーして記載する。 -
筆者は
/api/user
のリクエストのAuthタブのAccess Token部分に先のリクエストでの戻り値のaccess_token
を記載しリクエストを実行した。 -
下記の様な値が帰ってきた。
routes/api.php
に記載されている/user
のルーティングに紐づくクロージャーの処理が実行されユーザー情報が返された。{ "id": 1, "name": "test_user", "email": "test@example.com", "email_verified_at": null, "created_at": null, "updated_at": null }
-
上記の様に一回access_tokenが吐き出されたら、有効期限が切れるまでaccess_tokenを用いて通信を行う。access_tokenの有効期限が切れたら、refresh_tokenを用いてaccess_tokenとrefresh_tokenを再発行する。refresh_tokenの有効期限も切れてしまったら、ユーザーに再度ログインをお願いする。
使ってみる(Client Credentials Grant)
-
次にユーザー情報を必要としないClient Credetials Grantを使ってみる。ユーザー情報を必要としないのでシステムそのものからのAPI呼び出し時などにトークンを利用して認証する事ができる。
-
下記コマンドを実行してClient Credentials Grantのクライアントを作成する。(新しいクライアント情報がoauth_clientsテーブルに追加される。)
$ php artisan passport:client --client What should we name the client? [Laravel ClientCredentials Grant Client]: >クライアントの任意の名前を指定する事ができる。今回はデフォルトのままEnterを押下する。
-
クライアントのクレデンシャルチェック用のミドルウエアを追加して
routes/api.php
で指定してアクセス制限をかけられるようにする。app/Http/Kernel.php
を開く。$routeMiddleware
の配列の最後に下記の内容を追記する。(これでroutes/api.php
で->middleware(api:client)
のようにroutes/api.php
で指定できるようになった。)app/Http/Kernel.php'client' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
-
リクエストを送ることのできるツール(Postmanやthunder client)を用いて下記のリクエストを送る。
- リクエストの詳細
項目 値 備考 リクエスト送信URL /oauth/token 環境に応じて http://localhost:ポート番号
やhttp://127.0.0.1/oauth/token
として指定する。HTTPメソッド POST - POSTする値の情報(BodyのFormとして下記の値を送信する。)
項目 値 備考 grant_type client_credentials Client Credentials Grant Clientを使う指定 client_id 3 $ php artisan passport:client --client
を実行した時に
oauth_clientsテーブルに格納された
nameカラムの値が「Laravel ClientCredentials Grant Client」のレコードの
idカラムの値client_secret YDu9jKONVeS5eOgGwCEtuefcRT8rsIXEocHmVQhO $ php artisan passport:client --client
を実行した時に
oauth_clientsテーブルに格納された
nameカラムの値が「Laravel ClientCredentials Grant Client」のレコードの
secretカラムの値
※左に記載されている値は皆さんのものとは異なりますscope 何も入力しない -
筆者は下記のようなリクエストを送った。
-
下記のような値が帰ってきた。Password Grantの時と同じように認証が通り、アクセストークンとリフレッシュトークンが返された。
{ "token_type": "Bearer", "expires_in": 31536000, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiO・・・ }
-
あとはPassword Grantのときと同じ様に帰ってきた値の
access_token
を用いてリクエストを送ってみる。リクエストを送ることのできるツール(Postmanやthunder client)を用いて下記のリクエストを送る。- リクエストの詳細
項目 値 備考 リクエスト送信URL /api/user 環境に応じて http://localhost:ポート番号
やhttp://127.0.0.1/oauth/token
として指定する。HTTPメソッド GET - POSTする値の情報(AuthのOAuth 2に下記の項目を追加して送信する。)
項目 値 備考 Access Token eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiO・・・ 先のリクエストで戻ってきたaccess_tokenの値をすべてコピーして記載する。 -
筆者は下記のような情報でリクエストを送った。
-
Password Grantのときと同じように下記の様な値が帰ってきた。
routes/api.php
に記載されている/user
のルーティングに紐づくクロージャーの処理が実行されユーザー情報が返された。{ "id": 1, "name": "test_user", "email": "test@example.com", "email_verified_at": null, "created_at": null, "updated_at": null }