Laravel Sanctum
はじめに
Laravel Sanctum は、SPA(シングルページアプリケーション)、モバイルアプリケーション、およびシンプルなトークンベースのAPI向けの軽量な認証システムを提供します。Sanctum は、アプリケーションの各ユーザーが自分のアカウントに複数のAPIトークンを生成できるようにします。これらのトークンには、トークンが実行できるアクションを指定する権限/スコープが付与される場合があります。
動作原理
Laravel Sanctum は、2つの異なる問題を解決するために存在しています。ライブラリに詳しく入る前に、それぞれについて話し合いましょう。
API トークン
まず、Sanctum は、OAuthの複雑さなしにユーザーにAPIトークンを発行するために使用できるシンプルなパッケージです。この機能は、GitHubや他のアプリケーションが「パーソナルアクセストークン」を発行することに触発されています。たとえば、アプリケーションの「アカウント設定」に、ユ ーザーがアカウント用のAPIトークンを生成できる画面があるとします。Sanctum を使用して、これらのトークンを生成および管理できます。これらのトークンは通常、非常に長い有効期限(数年)を持っていますが、ユーザーがいつでも手動で取り消すことができます。
Laravel Sanctumは、ユーザーのAPIトークンを単一のデータベーステーブルに保存し、有効なAPIトークンを含む Authorization
ヘッダーを介して受信するHTTPリクエストを認証することで、この機能を提供します。
SPA認証
次に、Sanctumは、Laravelで動作するAPIと通信する必要があるシングルページアプリケーション(SPA)を簡単に認証する方法を提供するために存在しています。これらのSPAは、Laravelアプリケーションと同じリポジトリに存在するか、Vue CLIを使用して作成されたSPAやNext.jsアプリケーションなど、完全に別のリポジトリに存在するかもしれません。
この機能では、Sanctumはどのようなトークンも使用しません。代わりに、SanctumはLaravelの組み込みのクッキーベースのセッション認証サービスを使用します。通常、Sanctumはこれを達成するためにLaravelの web
認証ガードを利用します。これにより、CSRF保護、セッション認証、およびXSSを介した認証資格情報の漏洩から保護されます。
Sanctumは、受信したリクエストが自分自身のSPAフロントエンドから発信された場合にのみ、クッキーを使用して認証を試みます。Sanctumが受信したHTTPリクエストを調べるとき、まず認証クッキーをチェックし、存在しない場合は Authorization
ヘッダーを調べて有効なAPIトークンを探します。
SanctumをAPIトークン認証のみに使用するか、SPA認証のみに使用することも完全に問題ありません。Sanctumを使用するからといって、提供される両方の機能を使用する必要があるわけではありません。
インストール
Laravel Sanctumは、install:api
Artisanコマンドを使用してインストールできます:
php artisan install:api
次に、SPAを認証するためにSanctumを利用する予定がある場合は、このドキュメントの SPA認証 セクションを参照してください。
設定
デフォルトモデルの上書き
通常は必要ありませんが、Sanctumによって内部的に使用される PersonalAccessToken
モデルを拡張することができます。
use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
class PersonalAccessToken extends SanctumPersonalAccessToken
{
// ...
}
その後、Sanctumによって提供されるusePersonalAccessTokenModel
メソッドを使用して、カスタムモデルを使用するようにSanctumに指示できます。通常、このメソッドを、アプリケーションのAppServiceProvider
ファイルのboot
メソッド内で呼び出す必要があります:
use App\Models\Sanctum\PersonalAccessToken;
use Laravel\Sanctum\Sanctum;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
}
API トークン認証
自社の第一SPAを認証するためにAPIトークンを使用しないでください。代わりに、Sanctumの組み込みのSPA認証機能を使用してください。
APIトークンの発行
Sanctumを使用すると、アプリケーションへのAPIリクエストを認証するために使用できるAPIトークン/パーソナルアクセストークンを発行できます。APIトークンを使用してリクエストを行う場合、トークンはAuthorization
ヘッダーにBearer
トークンとして含める必要があります。
ユーザーにトークンを発行するためには、UserモデルがLaravel\Sanctum\HasApiTokens
トレイトを使用する必要があります:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
トークンを発行するには、createToken
メソッドを使用できます。createToken
メソッドはLaravel\Sanctum\NewAccessToken
インスタンスを返します。APIトークンは、データベースに保存される前にSHA-256ハッシュ化されますが、NewAccessToken
インスタンスのplainTextToken
プロパティを使用してトークンの平文値にアクセスできます。トークンが作成された直後に、この値をユーザーにすぐに表示する必要があります:
use Illuminate\Http\Request;
Route::post('/tokens/create', function (Request $request) {
$token = $request->user()->createToken($request->token_name);
return ['token' => $token->plainTextToken];
});
HasApiTokens
トレイトによって提供されるtokens
Eloquentリレーションシップを使用して、ユーザーのすべてのトークンにアクセスできます:
foreach ($user->tokens as $token) {
// ...
}
トークンの権限
Sanctumを使用すると、トークンに"権限"を割り当てることができます。権限は、OAuthの"スコープ"と同様の目的を果たします。createToken
メソッドの第2引数として、文字列の権限の配列を渡すことができます:
return $user->createToken('token-name', ['server:update'])->plainTextToken;
Sanctumによって認証された着信リクエストを処理する際に、tokenCan
メソッド を使用して、トークンに特定の権限があるかどうかを判断できます:
if ($user->tokenCan('server:update')) {
// ...
}
トークン能力ミドルウェア
Sanctumには、与えられた権限を持つトークンで認証されたリクエストかどうかを検証するために使用できる2つのミドルウェアも含まれています。始めるには、アプリケーションのbootstrap/app.php
ファイルで以下のミドルウェアエイリアスを定義してください:
use Laravel\Sanctum\Http\Middleware\CheckAbilities;
use Laravel\Sanctum\Http\Middleware\CheckForAnyAbility;
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'abilities' => CheckAbilities::class,
'ability' => CheckForAnyAbility::class,
]);
})
abilities
ミドルウェアは、リクエストのトークンがすべてのリストされた権限を持っていることを検証するためにルートに割り当てることができます:
Route::get('/orders', function () {
// Token has both "check-status" and "place-orders" abilities...
})->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);
ability
ミドルウェアは、リクエストのトークンがリストされた権限の少なくとも1つを持っていることを検証するためにルートに割り当てることができます:
Route::get('/orders', function () {
// Token has the "check-status" or "place-orders" ability...
})->middleware(['auth:sanctum', 'ability:check-status,place-orders']);