サイトを更新しています。 数日間、レイアウトや翻訳に不具合が出ることがあります。ドキュメントは引き続きご利用いただけます。表示が崩れている場合は、後ほど再読み込みしてください。

ホーム Laravel 10.x Laravel Sanctum

Laravel Sanctum

10.x 2026年3月7日

#はじめに

Laravel Sanctum は、SPA(シングルページアプリケーション)、モバイルアプリケーション、シンプルなトークンベースのAPI向けの軽量な認証システムを提供します。Sanctumでは、各ユーザーが複数のAPIトークンを生成でき、それらのトークンに対して許可された操作を指定する権限(abilities / scopes)を付与できます。

#仕組み

Laravel Sanctumは2つの異なる問題を解決するために存在します。まずはそれぞれについて説明し、その後ライブラリの詳細に進みます。

#APIトークン

まず、SanctumはOAuthの複雑さなしにユーザーにAPIトークンを発行できるシンプルなパッケージです。この機能はGitHubなどの「パーソナルアクセストークン」発行機能に触発されています。例えば、アプリケーションの「アカウント設定」画面でユーザーが自分のアカウント用にAPIトークンを生成できるとします。Sanctumを使えば、そのトークンの生成と管理が可能です。これらのトークンは通常、非常に長い有効期限(数年)を持ちますが、ユーザーがいつでも手動で取り消せます。

Laravel Sanctumは、ユーザーのAPIトークンを単一のデータベーステーブルに保存し、Authorization ヘッダーに有効なAPIトークンが含まれているかを検証してHTTPリクエストを認証することで、この機能を提供します。

#SPA認証

次に、SanctumはLaravelをバックエンドに持つAPIと通信する必要があるSPAを簡単に認証する方法を提供します。これらのSPAはLaravelアプリケーションと同じリポジトリに存在する場合もあれば、Vue CLIやNext.jsで作成された全く別のリポジトリの場合もあります。

この機能では、Sanctumはトークンを使用しません。代わりにLaravelの組み込みのクッキーセッション認証を利用します。通常、SanctumはLaravelの web 認証ガードを使ってこれを実現します。これによりCSRF保護やセッション認証が提供され、XSSによる認証情報の漏洩も防げます。

Sanctumは、リクエストが自分のSPAフロントエンドから発信された場合にのみクッキーを使った認証を試みます。リクエストを受け取ると、まず認証クッキーの有無を確認し、なければ Authorization ヘッダーに有効なAPIトークンがあるかをチェックします。

Примечание

SanctumをAPIトークン認証だけに使うことも、SPA認証だけに使うことも問題ありません。Sanctumを使うからといって両方の機能を使う必要はありません。

#インストール

Примечание

最新のLaravelにはすでにLaravel Sanctumが含まれています。ただし、アプリケーションの composer.jsonlaravel/sanctum が含まれていない場合は、以下のインストール手順に従ってください。

Laravel SanctumはComposerパッケージマネージャーでインストールできます:

composer require laravel/sanctum

次に、vendor:publish Artisanコマンドを使ってSanctumの設定ファイルとマイグレーションファイルを公開してください。sanctum の設定ファイルはアプリケーションの config ディレクトリに配置されます:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

最後に、データベースマイグレーションを実行してください。SanctumはAPIトークンを保存するためのテーブルを1つ作成します:

php artisan migrate

次に、SPA認証にSanctumを使う場合は、アプリケーションの app/Http/Kernel.php ファイル内の api ミドルウェアグループにSanctumのミドルウェアを追加してください:

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

#マイグレーションのカスタマイズ

Sanctumのデフォルトマイグレーションを使わない場合は、App\Providers\AppServiceProvider クラスの register メソッド内で Sanctum::ignoreMigrations メソッドを呼び出してください。デフォルトのマイグレーションは次のコマンドでエクスポートできます:php artisan vendor:publish --tag=sanctum-migrations

#設定

#デフォルトモデルのオーバーライド

通常は不要ですが、Sanctumが内部で使用する PersonalAccessToken モデルを拡張することもできます:

use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;

class PersonalAccessToken extends SanctumPersonalAccessToken
{
    // ...
}

その後、Sanctumの usePersonalAccessTokenModel メソッドを使ってカスタムモデルを指定できます。通常はアプリケーションのサービスプロバイダーの boot メソッド内で呼び出します:

use App\Models\Sanctum\PersonalAccessToken;
use Laravel\Sanctum\Sanctum;

/**
 * アプリケーションサービスの初期化。
 */
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 メソッドを使います。createTokenLaravel\Sanctum\NewAccessToken インスタンスを返します。APIトークンはデータベースに保存する前にSHA-256でハッシュ化されますが、NewAccessTokenplainTextToken プロパティでプレーンテキストのトークンを取得できます。トークン発行直後にユーザーにこの値を表示してください:

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ではトークンに「権限(abilities)」を割り当てられます。これはOAuthの「スコープ」と似た役割です。createToken メソッドの第2引数に文字列の権限配列を渡せます:

return $user->createToken('token-name', ['server:update'])->plainTextToken;

Sanctumで認証されたリクエストを処理する際、tokenCan メソッドでトークンに特定の権限があるか判定できます:

if ($user->tokenCan('server:update')) {
    // ...
}

#トークン権限ミドルウェア

Sanctumには、リクエストが特定の権限を持つトークンで認証されているか検証する2つのミドルウェアが含まれています。まず、アプリケーションの app/Http/Kernel.php ファイルの $middlewareAliases プロパティに以下を追加してください:

'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,

abilities ミドルウェアは、リクエストのトークンが指定したすべての権限を持つか検証します:

Route::get('/orders', function () {
    // トークンが "check-status" と "place-orders" の両方の権限を持つ場合...
})->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);

ability ミドルウェアは、リクエストのトークンが指定した権限のうち いずれか一つ を持つか検証します:

Route::get('/orders', function () {
    // トークンが "check-status" または "place-orders" の権限を持つ場合...
})->middleware(['auth:sanctum', 'ability:check-status,place-orders']);

#ファーストパーティUI発行リクエスト

利便性のため、Sanctumの tokenCan メソッドは、認証済みリクエストがファーストパーティSPAからのものでSanctumの組み込みSPA認証を使っている場合、常に true を返します。

ただし、これは必ずしもアプリケーションがユーザーにその操作を許可することを意味しません。通常はアプリケーションの認可ポリシーが、トークンに権限が付与されているかとユーザー自身がその操作を許可されているかを判定します。

例えば、サーバー管理アプリケーションを想定すると、トークンがサーバーの更新権限を持ち、かつそのサーバーがユーザーに属しているかを確認することになります:

return $request->user()->id === $server->user_id &&
       $request->user()->tokenCan('server:update')

最初は、ファーストパーティUI発行リクエストに対して tokenCan メソッドが常に true を返すのは不自然に思えるかもしれません。しかし、APIトークンが常に利用可能で tokenCan で検査できると仮定できるのは便利です。この方法なら、アプリケーションの認可ポリシー内でリクエストがUIからのものかAPIのサードパーティからのものかを気にせずに tokenCan を呼べます。

#ルートの保護

すべてのリクエストを認証済みにするには、routes/web.phproutes/api.php の保護したいルートに sanctum 認証ガードを適用してください。このガードは、リクエストがステートフルなクッキー認証済みか、サードパーティからのリクエストなら有効なAPIトークンを含むかを検証します。

なぜ routes/web.php のルートも sanctum ガードで認証することを推奨するのか疑問に思うかもしれません。SanctumはまずLaravelの通常のセッション認証クッキーで認証を試み、クッキーがなければ Authorization ヘッダーのトークンで認証を試みます。さらに、すべてのリクエストをSanctumで認証することで、現在認証中のユーザーインスタンスに対して常に tokenCan メソッドを呼べるようになります:

use Illuminate\Http\Request;

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

#トークンの取り消し

Laravel\Sanctum\HasApiTokens トレイトが提供する tokens リレーションシップを使って、データベースからトークンを削除し「取り消し」できます:

// すべてのトークンを取り消す...
$user->tokens()->delete();

// 現在のリクエストで使われているトークンを取り消す...
$request->user()->currentAccessToken()->delete();

// 特定のトークンを取り消す...
$user->tokens()->where('id', $tokenId)->delete();

#トークンの有効期限

デフォルトでは、Sanctum のトークンは期限切れにならず、トークンの取り消しによってのみ無効化されます。ただし、アプリケーションの API トークンに有効期限を設定したい場合は、アプリケーションの sanctum 設定ファイル内の expiration 設定オプションで指定できます。この設定オプションは、発行されたトークンが期限切れと見なされるまでの分数を定義します。

'expiration' => 525600,

各トークンの有効期限を個別に指定したい場合は、createToken メソッドの第3引数として有効期限を渡すことで設定できます。

return $user->createToken(
    'token-name', ['*'], now()->addWeek()
)->plainTextToken;

アプリケーションにトークンの有効期限を設定している場合は、スケジュールタスクを使って期限切れのトークンを削除することも検討してください。幸いなことに、Sanctum には sanctum:prune-expired という Artisan コマンドが用意されており、これを使って期限切れトークンを削除できます。例えば、少なくとも24時間期限切れのトークンをすべて削除するスケジュールタスクを設定できます。

$schedule->command('sanctum:prune-expired --hours=24')->daily();

#SPA 認証

Sanctum は、Laravel をバックエンドに持つ API と通信するシングルページアプリケーション(SPA)を簡単に認証する方法も提供します。これらの SPA は Laravel アプリケーションと同じリポジトリに存在する場合もあれば、まったく別のリポジトリで管理されている場合もあります。

この機能では、Sanctum はトークンを使用しません。代わりに、Laravel の組み込みのクッキーを使ったセッション認証サービスを利用します。この認証方法は、CSRF 保護やセッション認証の利点を提供し、XSS による認証情報の漏洩も防ぎます。

Внимание

認証を行うには、SPA と API が同じトップレベルドメインを共有している必要があります。ただし、異なるサブドメインに配置しても問題ありません。さらに、リクエストには Accept: application/json ヘッダーと、Referer または Origin ヘッダーのいずれかを必ず送信してください。

#設定

#ファーストパーティドメインの設定

まず、SPA がリクエストを送信するドメインを設定します。これらのドメインは、sanctum 設定ファイルの stateful オプションで指定できます。この設定は、API へのリクエスト時に Laravel のセッションクッキーを使った「ステートフル」認証を維持するドメインを決定します。

Внимание

ポート番号を含む URL(例:127.0.0.1:8000)でアプリケーションにアクセスする場合は、ドメインにポート番号も含めるようにしてください。

#Sanctum ミドルウェア

次に、app/Http/Kernel.php ファイルの api ミドルウェアグループに Sanctum のミドルウェアを追加します。このミドルウェアは、SPA からのリクエストが Laravel のセッションクッキーを使って認証できるようにしつつ、サードパーティやモバイルアプリからのリクエストは API トークンで認証できるようにします。

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

#CORS とクッキー

別のサブドメインで実行される SPA からアプリケーションに認証できない場合は、CORS(クロスオリジンリソースシェアリング)やセッションクッキーの設定が誤っている可能性があります。

アプリケーションの CORS 設定で、Access-Control-Allow-Credentials ヘッダーが True の値で返されていることを確認してください。これは、config/cors.php 設定ファイルの supports_credentials オプションを true に設定することで実現できます。

さらに、アプリケーションのグローバルな axios インスタンスで withCredentialswithXSRFToken オプションを有効にしてください。通常は resources/js/bootstrap.js ファイルで設定します。Axios を使わずに HTTP リクエストを送る場合は、同等の設定を自分の HTTP クライアントで行ってください。

axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;

最後に、アプリケーションのセッションクッキーのドメイン設定がルートドメインの任意のサブドメインをサポートしていることを確認してください。これは、config/session.php 設定ファイルでドメインの先頭に . を付けることで実現できます。

'domain' => '.domain.com',

#認証

#CSRF 保護

SPA を認証するには、まず SPA の「ログイン」ページで /sanctum/csrf-cookie エンドポイントにリクエストを送り、アプリケーションの CSRF 保護を初期化します。

axios.get('/sanctum/csrf-cookie').then(response => {
    // ログイン...
});

このリクエスト中に、Laravel は現在の CSRF トークンを含む XSRF-TOKEN クッキーを設定します。このトークンは、その後のリクエストで X-XSRF-TOKEN ヘッダーに渡す必要があります。Axios や Angular HttpClient のような一部の HTTP クライアントライブラリはこれを自動で行います。もし JavaScript の HTTP ライブラリが自動で設定しない場合は、このルートで設定された XSRF-TOKEN クッキーの値と一致するように X-XSRF-TOKEN ヘッダーを手動で設定してください。

#ログイン

CSRF 保護が初期化されたら、Laravel アプリケーションの /login ルートに POST リクエストを送ります。この /login ルートは、手動で実装するか、Laravel Fortify のようなヘッドレス認証パッケージを使って実装できます。

ログインリクエストが成功すると認証され、その後のアプリケーションのルートへのリクエストは、Laravel アプリケーションがクライアントに発行したセッションクッキーを使って自動的に認証されます。さらに、アプリケーションはすでに /sanctum/csrf-cookie ルートにリクエストを送っているため、JavaScript の HTTP クライアントが XSRF-TOKEN クッキーの値を X-XSRF-TOKEN ヘッダーに送信していれば、その後のリクエストは自動的に CSRF 保護を受けます。

もちろん、ユーザーのセッションが非アクティブによって期限切れになると、その後の Laravel アプリケーションへのリクエストは 401 または 419 の HTTP エラーを受け取る可能性があります。この場合は、ユーザーを SPA のログインページにリダイレクトしてください。

Внимание

独自の /login エンドポイントを作成しても構いませんが、必ず Laravel が提供する標準のセッションベース認証サービスを使ってユーザーを認証するようにしてください。通常は web 認証ガードを使います。

#ルートの保護

すべてのリクエストに認証を要求するには、routes/api.php ファイルの API ルートに sanctum 認証ガードを適用します。このガードは、SPA からのステートフル認証リクエストか、サードパーティからの有効な API トークンを含むリクエストかを判別して認証します。

use Illuminate\Http\Request;

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

#プライベートブロードキャストチャンネルの認可

SPA がプライベート / プレゼンスブロードキャストチャンネルを認証する必要がある場合は、routes/api.php ファイルに Broadcast::routes メソッドを配置してください。

Broadcast::routes(['middleware' => ['auth:sanctum']]);

次に、Pusher の認可リクエストを成功させるために、Laravel Echo を初期化する際にカスタムの Pusher authorizer を提供する必要があります。これにより、アプリケーションは クロスドメインリクエストに対して適切に設定された axios インスタンスを使用するように Pusher を構成できます:

window.Echo = new Echo({
    broadcaster: "pusher",
    cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
    encrypted: true,
    key: import.meta.env.VITE_PUSHER_APP_KEY,
    authorizer: (channel, options) => {
        return {
            authorize: (socketId, callback) => {
                axios.post('/api/broadcasting/auth', {
                    socket_id: socketId,
                    channel_name: channel.name
                })
                .then(response => {
                    callback(false, response.data);
                })
                .catch(error => {
                    callback(true, error);
                });
            }
        };
    },
})

#モバイルアプリケーション認証

Sanctum トークンは、モバイルアプリケーションの API リクエスト認証にも使えます。モバイルアプリの認証プロセスはサードパーティの API リクエスト認証に似ていますが、API トークンの発行方法に若干の違いがあります。

#API トークンの発行

まず、ユーザーのメールアドレス/ユーザー名、パスワード、デバイス名を受け取り、それらの認証情報を新しい Sanctum トークンと交換するルートを作成します。この「デバイス名」は情報用で、任意の値を指定できます。一般的には、ユーザーが認識しやすい名前(例:「Nuno の iPhone 12」)を使います。

通常は、モバイルアプリの「ログイン」画面からこのトークン発行エンドポイントにリクエストを送ります。エンドポイントはプレーンテキストの API トークンを返し、それをモバイル端末に保存して追加の API リクエストに使います。

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

Route::post('/sanctum/token', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
    ]);

    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'email' => ['提供された認証情報が正しくありません。'],
        ]);
    }

    return $user->createToken($request->device_name)->plainTextToken;
});

モバイルアプリがこのトークンを使って API リクエストを送る際は、Authorization ヘッダーに Bearer トークンとして渡してください。

Примечание

モバイルアプリ用にトークンを発行する際は、トークンの権限を指定しても構いません。

#ルートの保護

前述の通り、すべてのリクエストに認証を要求するには、sanctum 認証ガードをルートに適用します。

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

#トークンの取り消し

ユーザーがモバイルデバイスに発行された API トークンを取り消せるように、Web アプリケーションの「アカウント設定」画面などでトークン名と「取り消し」ボタンを一覧表示できます。ユーザーが「取り消し」ボタンを押すと、データベースからトークンを削除できます。ユーザーの API トークンには、Laravel\Sanctum\HasApiTokens トレイトが提供する tokens リレーションからアクセスできます。

// すべてのトークンを取り消す...
$user->tokens()->delete();

// 特定のトークンを取り消す...
$user->tokens()->where('id', $tokenId)->delete();

#テスト

テスト時には、Sanctum::actingAs メソッドを使ってユーザーを認証し、そのトークンに付与する権限を指定できます。

use App\Models\User;
use Laravel\Sanctum\Sanctum;

public function test_task_list_can_be_retrieved(): void
{
    Sanctum::actingAs(
        User::factory()->create(),
        ['view-tasks']
    );

    $response = $this->get('/api/task');

    $response->assertOk();
}

すべての権限をトークンに付与したい場合は、actingAs メソッドの権限リストに * を含めてください。

Sanctum::actingAs(
    User::factory()->create(),
    ['*']
);