1. Blade でフォームを構築する基本
| 要素 | 役割 | Blade での記述例 |
|---|---|---|
<form> タグ |
送信先 URL と HTTP メソッドを定義 | <form method="POST" action="{{ route('posts.store') }}"> |
| CSRF トークン | Laravel が期待する _token フィールドを生成 |
@csrf |
| メソッドスプーフィング | HTML がサポートしない PUT / PATCH / DELETE を疑似的に送信 |
@method('PUT') |
-
Laravel ではフォームヘルパを必要とせず、純粋な HTML と Blade ディレクティブのみでフォームを組み立てられます。
-
送信ボタンなど他の要素は通常の HTML と同様に配置します。
-
old('field')を使うとバリデーションエラー後に入力値を再表示できます。 laravel.comlaravel.com
2. CSRF(Cross-Site Request Forgery)保護の仕組み
-
トークン発行
-
初回リクエスト時、Laravel はセッションと紐付いた ランダムな CSRF トークン を生成し、レスポンスの Cookie(
XSRF-TOKEN)とサーバ側セッションに保存します。
-
-
フォーム埋め込み
-
Blade の
@csrfが隠し入力<input type="hidden" name="_token" value="…">を生成し、上記トークンをフォーム内に埋め込みます。
-
-
検証
-
フォーム送信時、
VerifyCsrfTokenミドルウェアが Cookie とフォーム値 を比較し、一致しない場合は 419(Page Expired)を返します。 -
トークンは POST・PUT・PATCH・DELETE リクエストで自動検証されます。 laravel.comlaravel.com
-
3. Laravel 11 での変更点
| 項目 | Laravel 10 以前 | Laravel 11 以降 |
|---|---|---|
| ミドルウェアの場所 | app/Http/Middleware/VerifyCsrfToken.php |
フレームワーク側に同梱(vendor 配下) |
| 除外ルートの定義 | ミドルウェアの $except 配列 |
bootstrap/app.php の csrf.except 設定キーにパスを列挙 |
| カスタムミドルウェア | 既存ファイルを継承して差し替え | 独自ミドルウェアを作成し、csrf.middleware 設定を上書き |
-
アプリ側にミドルウェアが存在しない ため、CSRF を除外したいルートや SPA/API 用にカスタマイズする際は
bootstrap/app.phpに設定を追記します。 -
アップグレード時に「CSRF token mismatch」が多発する場合は、設定漏れやキャッシュを確認します。 stackoverflow.comlaracasts.com
4. JavaScript/Ajax と CSRF
| シナリオ | 推奨手順 |
|---|---|
| Axios/Fetch | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name=\"csrf-token\"]').content; |
| Livewire, Inertia.js | フレームワーク側で自動付与されるため追加不要 |
| API(Bearer 認証) | 通常は CSRF を無効化 し、代わりに Laravel Sanctum などのトークン認証を採用 |
-
@csrfディレクティブは<meta name="csrf-token">も併せて出力するため、フロントエンドからヘッダーに転用できます。 medium.com
5. CSRF 保護に関するベストプラクティス
-
常に
@csrfを使用-
例外は GET リクエストのみ(状態を変えないため)。
-
-
セッション有効期限と同時にトークンも期限切れ
-
長時間フォームを開いたまま送信すると 419 エラーになり得るため、UX 改善にはフロント側リロードや自動トークン更新を検討。
-
-
例外ルートは最小限に
-
WebHook 受信など正当な理由がある場合だけ
csrf.exceptへ追加。
-
-
セキュリティヘッダ併用
-
SameSite=Lax/Strict、Content-Security-Policyも合わせて設定すると総合的な CSRF 耐性が向上します。 dev.to
-
6. よくあるトラブルシューティング
| 症状 | 主な原因 | 対処 |
|---|---|---|
| 419 Page Expired | フォームに _token が含まれていない |
@csrf の記述漏れを確認 |
| Token Mismatch | Cookie が更新され、古いフォームを送信 | セッション期限を延長する/ページをリロード |
| SPA で 419 | Axios にヘッダーが無い | <meta name="csrf-token"> を読み込ませる |
| 外部サービス POST 失敗 | CSRF により拒否 | csrf.except で該当パスを除外しつつ入力検証を強化 |
まとめ
-
@csrfはフォームに必須。Blade でワンライナー生成でき、メソッドスプーフィングと併用して RESTful ルートを安全に呼び出せます。 -
検証は
VerifyCsrfTokenミドルウェアが担い、Laravel 11 からはフレームワーク組込みで設定ファイル経由の管理へ変更されました。 -
Ajax / SPA でも
X-CSRF-TOKENヘッダー を正しく送れば検証は通過します。API は CSRF を無効化してトークン認証(Sanctum 等)を利用するのが一般的です。 -
トークン不一致エラー時は Cookie, セッション, キャッシュ を順に確認し、ルート除外は最終手段と考えてください。
ChatGPT4o 生成日:2025/06/23