Laravel をバックエンドとして Laravel Sanctum を使用して SPA 認証機能を実装する。
概要
フロントを React で開発している。そこにバックエンド開発として Laravel を採用した。そこで認証機能を Laravel Sanctum を使用して SPA 認証機能を実装する。
React は localhost:3000, Laravel は localhost:8000 を使用している。
環境
- Windows 10 Home
- php: 8.0.10
- composer: 2.1.7
- Laravel: ^8.75
Laravel の認証機能
今回は Laravel Sanctum を使用する。
Laravel Sanctum の準備
composer.json の require のリストに laravel/sanctum が記載がない場合は以下を実行
composer require laravel/sanctum
次に、初期設定では Sanctum の設定ファイル等が非表示になっているため Artisan コマンドを使用して該当ファイルを表示可能にする。
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
今回は SPA認証のみを行うため、APIトークンを格納するためのテーブルを作成する必要はない。
また、上記で作成された database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php ファイルは不要なので削除する。
また、上記のマイグレーションファイルを削除しただけでは、マイグレーション実行時に personal_access_tokens のテーブルが作成されてしまうため、これを無効化する必要がある。
その概要については以下を参考にする。
最後に app/Http/Kernel.php ファイル内の api ミドルウェアグループ内に以下を追記する。
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // 追記
'その他'
],
SPA認証の実装
はじめにファーストパーティドメインの設定をする必要がある。この設定はデフォルトで config/sanctum.php の stateful に記載されており、デフォルトでは下記のようになっている。
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
今回、フロントエンド開発に使用してる React は localhost:3000 で接続することができるので設定を変更する必要はないが、定義されていない FQDN を使用する場合は別途、以下を参考に環境ファイルに定義する必要がある。
SANCTUM_STATEFUL_DOMAINS={FQDN}
次に、双方のアプリケーションに対してcorsの設定を行う必要がある。
Laravel 側のcorsの設定は config/cors.php に記載されており、このファイル内の supports_credentials を true に変更する必要がある。
<?php
return [
... ,
'supports_credentials' => true,
]
また、React 側の設定は、axios を使用する場合、デフォルトでは withCredentials の値が false になっているので、これを true に変更する。今回は、axios をインスタンス化する際に設定しておく。
axios.create({
... ,
withCredentials: true,
})
Laravelアプリケーションのセッションクッキードメイン設定をします。
アプリケーションのconfig/session.php設定ファイル内でドメインの先頭に.を付けます。
'domain' => '.domain.com',
※ localhostで開発している場合は設定する必要はない。
コンソールにこのように表示された場合は成功
{data: '', status: 204, statusText: 'No Content', headers: {…}, config: {…}, …}
Laravel Fortify の準備
はじめに、Fortify をインストールする。
composer require laravel/fortify
次に、Laravel Sanctum の時と同様に初期設定では Fortify の設定ファイル等が非表示になっているため Artisan コマンドを使用して該当ファイルを表示可能にする。
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
ここで、config/app.php 内の providers 配列内に App\Providers\FortifyServiceProvider クラスが登録されていることを確認する。仮に登録されていない場合は以下を追記する。
<?php
return
... ,
'providers' => [
... ,
App\Providers\FortifyServiceProvider::class, // 追記
]
最後に、データベースをマイグレーションする。
php artisan migrate
Laravel Fortify でログイン
まず、config/fortify.php 内の View の設定が true になっているので、false に変更する。
'views' => false,
これによって Laravel 側でログインや登録画面を表示するためのルートが削除される。
実際に、php artisan route:list > routes.txt コマンドで定義されているルートを書き出して確認すると true から false に変更するにあたって
| | GET|HEAD | login | login | Laravel\Fortify\Http\Controllers\AuthenticatedSessionController@create | web |
| | GET|HEAD | register | register | Laravel\Fortify\Http\Controllers\RegisteredUserController@create | web |
などのルートが定義されていない状態になっていることが確認できる。
Discussion