INSIGHT

情報・インサイト

Laravel PassportでWeb APIの認証を実装する【初期設定編】

2018.04.12

システム部の髙橋です。

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を叩いてみるまでを行います。

参考文献

WORKS

導入事例

ウィズテクノロジーは大阪を拠点に、システム開発の分野で20年の実績を持つパートナー企業です。
業務効率化やDX支援など、さまざまな課題にワンストップで対応。
経験豊富なエンジニアが、企業の成長を技術面からしっかりサポートします。

導入事例一覧を見る
導入事例一覧を見る

RECRUIT

採用情報

未来に、価値ある選択を。

All WhizzTechnologyは、期待を超える価値をともにつくり、より良い未来へ導く仲間を募集しています。