Laravel PassportでWeb APIの認証を実装する【初期設定編】
システム部の髙橋です。
Laravel Passportで、Web APIの認証を実装するチュートリアルです。
このチュートリアルでは、最終的に以下のようなAPI認証を実装することを目的としています。
① EmailとPasswordでWebアプリにログインする
② 管理画面で自身に紐づくTokenを発行、確認する
③ Tokenをリクエストヘッダーに含め、Web APIを利用する
今回は、初期設定編と題して、まずLaravel Passportの初期設定の方法を紹介します。
Laravel Passportとは
Laravel passportは、LaravelによるWeb APIの認証の実装をサポートするライブラリです。
Laravel上で、OAuth2によるWeb APIの認証が実装できるようになります。
特徴としては、複数の認証フローをサポートすることなどがあげられます。
初めにやっておくこと
Composerをインストールし、Laravelのプロジェクトを新規作成、初期設定をしておいてください。
ComposerとLaravelのインストールは、Laravelの公式ドキュメントを参考にしてください。
Laravel Passportの初期設定
Laravelのプロジェクトが用意出来たら、Laravel Passportの初期設定を行っていきます。
Laravel Passportを依存性に追加する
ComposerでLaravel Passportを依存性に追加します。
1 |
$ composer require laravel/passport |
Laravel Passportは、Package Auto-Discoveryに対応しています。
Package Auto-Discoveryは、Laravel用のパッケージの、ServiceProviderおよび Facadeの自動検出の仕組みです。
これにより、Laravel Passportを別途サービスプロバイダに追加する必要はなくなりました。
テーブルのマイグレーションを行う
以下のコマンドでDBに必要なテーブルを用意します。
1 |
$ php artisan migrate |
これにより、以下のLaravel Passport関連テーブルが作成されます。
- oauth_access_tokens
- oauth_auth_codes
- oauth_clients
- oauth_personal_access_clients
- oauth_refresh_tokens
なぜLaravel Passportテーブルが作成されたのか
Package Auto-Discoveryにより、Passportのサービスプロバイダが追加されています。
Passportのサービスプロバイダは、Laravelに対し、自身のマイグレーションディレクトリを登録します。
それにより、マイグレーションを実行時に関連するテーブルを作成してくれるようになっているのです。
トークン作成時に使用されるキーを生成する
キーを生成するために、passport:install
というartisanコマンドを実行します。
1 |
$ php artisan passport:install |
このコマンドは、実際には以下の3つを生成します。
- 安全なアクセストークンを生成するのに必要な暗号キー
- アクセストークンの生成に使う、「パーソナルアクセス」クライアント
- アクセストークンの生成に使う、「パスワードグラント」クライアント
暗号キーは、/storage/
以下に作成され、クライアントは、データベースのレコードとして作成されます。
この中でも、パーソナルアクセスクライアントは、後に利用しますので頭の片隅に置いておいてください。
ソースコードを修正する
行うことは以下の3つです。
- Userモデルに、ヘルパメソッドを実装したトレイトを追加する
- AuthServiceProviderにルートを登録する
- config/auth.phpでパスポートのToken Guardを使用するよう設定する
Userモデルに、ヘルパメソッドを実装したトレイトを追加する
app/User.php
を以下のようにを編集してください。
① Laravel\Passport\HasApiTokensをインポートする
② HasApiTokensトレイトをUserモデルに追加する
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php namespace App; use Laravel\Passport\HasApiTokens; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use HasApiTokens, Notifiable; } |
これにより、UserモデルからLaravel Passportのヘルパメソッドが利用できるようになります。
ヘルパメソッドには、認証済みユーザーのトークンとスコープを確認するためのメソッドなどがあります。
AuthServiceProviderにルートを登録する
エディターでapp/Providers/AuthServiceProvider.php
を開き、以下ように編集してください。
① Laravel\Passport\Passportをインポートする
② bootメソッド内部で、Passport::routesメソッドを呼び出す
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php namespace App\Providers; use Laravel\Passport\Passport; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { // ... /** * 全認証/認可サービスの登録 * * @return void */ public function boot() { $this->registerPolicies(); Passport::routes(); } } |
これにより、以下のようなルートが登録されます。
- アクセストークンの発行
- アクセストークンの失効
- クライアントとパーソナルアクセストークンの管理
config/auth.phpでパスポートのToken Guardを使用するよう設定する
パスポートのToken Guardを使用するよう、config/auth.php
を編集します。
以下のようにガードのapi認証のdriverオプションをpassportへ設定します。
1 2 3 4 5 6 7 8 9 10 11 |
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ], |
これにより、パスポートのToken Guardが使用されるようになります。
動作確認のための自動テストを行う
ここまでで、Laravel Passportの初期設定が完了しました。
ちゃんと動作しているか確認の意味も含め、PHPUnitによる自動テストを行います。
composer.jsonにtestコマンドを定義する
composer.jsonにコマンドを定義することで、簡単に任意のコマンドが実行できます。
今回は、testというコマンドを定義して、phpunitを実行するようにします。
1 2 3 |
"scripts": { "test": "phpunit", }, |
以降は、以下のコマンドで自動テストが実行できるようになります。
1 |
$ comopser test |
Laravel Passportのテストの基底クラスを作成する
tests/
直下に、PassportTestCase.php
という名前でPHPファイルを作成します。
これを継承したテストのテストケース実行前に、以下のことを行うようになります。
① Personal Access ClientをDBに作成
② ユーザーと、それに紐づく認証TokenをDBに作成
③ リクエストのヘッダーを設定
コードは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php namespace Tests; use Tests\TestCase; use App\User; use Laravel\Passport\ClientRepository; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\DB; class PassportTestCase extends TestCase { use DatabaseTransactions; protected $headersWithToken = []; protected $headersWithoutToken = []; protected $scopes = []; protected $user; public function setUp() { parent::setUp(); // Personal Access ClientをDBに作成 $clientRepository = new ClientRepository(); $client = $clientRepository->createPersonalAccessClient( null, 'Test Personal Access Client', url('/') ); DB::table('oauth_personal_access_clients')->insert([ 'client_id' => $client->id, 'created_at' => new \DateTime, 'updated_at' => new \DateTime, ]); // ユーザーと、それに紐づく認証TokenをDBに作成 $this->user = factory(User::class)->create(); $token = $this->user->createToken('TestToken', $this->scopes)->accessToken; // リクエストのヘッダーを設定 $this->headersWithToken['Accept'] = 'application/json'; $this->headersWithToken['Authorization'] = 'Bearer '.$token; $this->headersWithoutToken['Accept'] = 'application/json'; } } |
ファイルの作成後、以下のコマンドを実行して、オートロードをしてください。
1 |
$ composer dumpautoload |
Laravel Passportの認証に対するテストを行う
以下の2つのケースでテストケースを作成します。
① /api/user
に対し、認証Tokenありでリクエストするテスト
② /api/user
に対し、認証Tokenなしでリクエストするテスト
/api/user
は認証が必要なエンドポイントです。
ここを叩けるかでAPIの認証が行われているかテストできます。
tests/Feature
の下に、UserApiTest.php
というファイルを作成してください。
ファイルの内容は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace Tests\Feature; use Tests\PassportTestCase; use Illuminate\Foundation\Testing\RefreshDatabase; class UserApiTest extends PassportTestCase { /** * /api/userに対し、認証Tokenありでリクエストするテスト */ public function testGetApiUserWithTokenInHeaders() { $this->get('/api/user', $this->headersWithToken)->assertStatus(200); } /** * /api/userに対し、認証Tokenなしでリクエストするテスト */ public function testGetApiUserWithOutTokenInHeaders() { $this->get('/api/user', $this->headersWithoutToken)->assertStatus(401); } } |
クラスの作成後、以下のコマンドでテストが成功すれば初期設定編は完了です。
1 |
$ composer test |
まとめ
今回は、Laravel Passportの初期設定を行いました。
続編の実装編では、実際にWebUIで、認証Tokenを発行し、APIを叩いてみるまでを行います。