
Summary
この文書の要点
- SanctumのSPA認証ではCookieとCSRFの前提を理解する。
- CORS設定は広げすぎず、環境ごとに許可オリジンを管理する。
- ログイン成功ではなく、CSRF取得、Cookie送信、セッション再確認までを一連のフローとして見る。
- CORS設定とCookie属性は環境別に検証し、localhostだけで判断しない。
どこが設計の難所か
Laravel Sanctumを導入しても、CORSを広く許可したり、CSRFトークン取得を省略したり、認証済みならすべてのAPIを通してしまうと、SPAとしての安全性が下がります。
ローカル開発、ステージング、本番ではドメインやHTTPSの条件が異なります。Cookie属性、SameSite、Secure、セッションドメインの設定が環境ごとにずれると、ログインできない問題や意図しない送信が起きます。
Laravel SanctumはSPA認証を扱いやすくしますが、動かない時の原因はLaravelコードだけにありません。SameSite、Secure、ドメイン、CORS、プロキシ、HTTPSの有無が絡むため、環境差で再現しにくい失敗が起きます。
境界をどう切るか
認証フローは、CSRF Cookie取得、ログイン、セッション確認、権限取得、API呼び出しに分けて考えます。フロントエンドはログイン済みかどうかだけでなく、利用できる機能をAPIから取得し、表示制御とAPI権限チェックを分けます。
設計では、認証をログインAPI単体ではなく、CSRF Cookie取得、ログイン、認証済みユーザー取得、ログアウト、期限切れの流れとして定義します。React側も401を単なるエラーではなく、セッション状態の変化として扱います。
実装で効く細部
Laravel側では、Sanctumのstatefulドメイン、CORS許可オリジン、セッションCookie設定を環境変数で管理します。React側では401と419を区別し、セッション切れは再ログインへ、権限不足は権限エラーとして扱います。
実装では、APIクライアントに`credentials: include`を固定し、CSRF取得をログイン前の明示ステップにします。Laravel側ではstateful domains、session domain、CORS origins、SameSiteを環境変数で管理し、本番とローカルの差を設定で吸収します。
- 401、419、403を分け、未ログイン、CSRF不一致、権限不足を同じ表示にしない。
- ログアウト時はサーバーセッションを破棄し、クライアント側のキャッシュも消す。
- 管理画面ではログイン直後だけでなく、ページ再読み込み時のユーザー復元を検証する。
壊れ方を観測する
検証では、別オリジンからの不正リクエスト、CSRFなしのPOST、期限切れセッション、ログアウト後のAPI呼び出し、権限不足の更新をテストします。ブラウザでCookie属性も確認します。
検証では、ローカル、ステージング、本番相当のHTTPS環境でCookieが送られるかを確認します。特に、別サブドメイン構成、リバースプロキシ配下、ブラウザのサードパーティCookie制限に近い条件を見ます。
捨てた選択肢とトレードオフ
CookieベースのSPA認証はブラウザとの相性が良い一方で、CORSやCSRFの設定を正しく理解する必要があります。モバイルアプリや外部API公開が主目的なら、トークン方式の方が適する場合もあります。
CookieベースのSPA認証はブラウザ標準と相性が良い一方、環境設定に敏感です。Bearer token方式はAPIクライアントから扱いやすいものの、保存場所と漏えい時のリスクが増えます。管理画面の用途では、CookieとCSRFを正しく設計する価値があります。
現場に残す判断軸
SanctumはSPA認証を簡単に始められる道具ですが、設定を広げすぎると安全性が落ちます。Cookie、CSRF、CORS、権限を一連の契約として扱うことが安定運用の前提です。
Sanctum認証は、Laravelの機能を有効にする作業ではなく、ブラウザとサーバーの信頼境界を揃える作業です。失敗コードを分けて観測できるようにすると、認証まわりの保守性が上がります。


