課題解決
INSIGHT
情報・インサイト
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を依存性に追加します。
$ composer require laravel/passport
Laravel Passportは、Package Auto-Discoveryに対応しています。
Package Auto-Discoveryは、Laravel用のパッケージの、ServiceProviderおよび Facadeの自動検出の仕組みです。
これにより、Laravel Passportを別途サービスプロバイダに追加する必要はなくなりました。
テーブルのマイグレーションを行う
以下のコマンドでDBに必要なテーブルを用意します。
$ 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コマンドを実行します。
$ php artisan passport:install
このコマンドは、実際には以下の3つを生成します。
- 安全なアクセストークンを生成するのに必要な暗号キー
- アクセストークンの生成に使う、「パーソナルアクセス」クライアント
- アクセストークンの生成に使う、「パスワードグラント」クライアント
暗号キーは、/storage/以下に作成され、クライアントは、データベースのレコードとして作成されます。
この中でも、パーソナルアクセスクライアントは、後に利用しますので頭の片隅に置いておいてください。
ソースコードを修正する
行うことは以下の3つです。
- Userモデルに、ヘルパメソッドを実装したトレイトを追加する
- AuthServiceProviderにルートを登録する
- config/auth.phpでパスポートのToken Guardを使用するよう設定する
Userモデルに、ヘルパメソッドを実装したトレイトを追加する
app/User.phpを以下のようにを編集してください。
① Laravel\Passport\HasApiTokensをインポートする
② HasApiTokensトレイトをUserモデルに追加する
<?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メソッドを呼び出す
<?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へ設定します。
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
これにより、パスポートのToken Guardが使用されるようになります。
動作確認のための自動テストを行う
ここまでで、Laravel Passportの初期設定が完了しました。
ちゃんと動作しているか確認の意味も含め、PHPUnitによる自動テストを行います。
composer.jsonにtestコマンドを定義する
composer.jsonにコマンドを定義することで、簡単に任意のコマンドが実行できます。
今回は、testというコマンドを定義して、phpunitを実行するようにします。
"scripts": {
"test": "phpunit",
},
以降は、以下のコマンドで自動テストが実行できるようになります。
$ comopser test
Laravel Passportのテストの基底クラスを作成する
tests/直下に、PassportTestCase.phpという名前でPHPファイルを作成します。
これを継承したテストのテストケース実行前に、以下のことを行うようになります。
① Personal Access ClientをDBに作成
② ユーザーと、それに紐づく認証TokenをDBに作成
③ リクエストのヘッダーを設定
コードは以下になります。
<?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';
}
}
ファイルの作成後、以下のコマンドを実行して、オートロードをしてください。
$ composer dumpautoload
Laravel Passportの認証に対するテストを行う
以下の2つのケースでテストケースを作成します。
① /api/userに対し、認証Tokenありでリクエストするテスト
② /api/userに対し、認証Tokenなしでリクエストするテスト
/api/userは認証が必要なエンドポイントです。
ここを叩けるかでAPIの認証が行われているかテストできます。
tests/Featureの下に、UserApiTest.phpというファイルを作成してください。
ファイルの内容は以下になります。
<?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);
}
}
クラスの作成後、以下のコマンドでテストが成功すれば初期設定編は完了です。
$ composer test
まとめ
今回は、Laravel Passportの初期設定を行いました。
続編の実装編では、実際にWebUIで、認証Tokenを発行し、APIを叩いてみるまでを行います。