◀ 41.

Laravelにおけるcsrfの有効時間を変更する方法

▶
この記事の要点
  • Laravel の CSRF トークンはセッションに保存されるため、有効時間=セッションの有効時間
  • 変更箇所は config/session.php の lifetime。実際には .env の SESSION_LIFETIME(分単位)を変える
  • デフォルトは 120 分。最後のアクセスから数えるので、操作が続いていれば切れない
  • 設定をキャッシュしている環境では php artisan config:cache で反映し直す
  • 長く伸ばしすぎるのはセキュリティ上不利。長いフォームは「期限切れ時に入力を残して戻す」対策と組み合わせる

結論: SESSION_LIFETIME を変更する

Laravel で CSRF トークンの有効時間を延ばしたい(または短くしたい)場合は、セッションの有効時間を変更します。CSRF トークン専用の有効期限設定はありません。

config/session.php に次の項目があります。

'lifetime' => env('SESSION_LIFETIME', 120),

Laravel 11 以降では (int) env('SESSION_LIFETIME', 120) のように整数へキャストする書き方になっていますが、意味は同じです。上記が修正箇所で、値は .env の SESSION_LIFETIME から読み込まれます。つまり、通常は .env ファイルを変更するだけで済みます。

# .env (単位は分。例: 8 時間)
SESSION_LIFETIME=480

.env に SESSION_LIFETIME の行がない場合は、config/session.php の第 2 引数(既定値 120)が使われます。

仕組み: なぜセッションの時間を変えるのか

Laravel はセッション開始時に CSRF トークンを生成し、セッションデータの一部として保存します。フォームに埋め込まれたトークン(@csrf)と、セッション内のトークンが一致するかを POST のたびに検証します。

  • セッションが期限切れで消える → サーバー側のトークンがなくなる → 一致しない
  • その結果、HTTP ステータス 419(Page Expired)のエラー画面になる

そのため、トークンの寿命を変えたければセッションの寿命を変える、という関係になります。

lifetime は「最後にアクセスしてからの分数」です。120 分なら、ページを開いたまま 2 時間以上何も操作せずに送信すると期限切れになります。途中で別のページを開くなどしてリクエストがあれば、その時点から数え直されます。

反映されないときの確認ポイント

症状原因と対処
.env を変えても変わらない設定がキャッシュされている。php artisan config:cache でキャッシュを作り直す
設定値は正しいのに早く切れるブラウザを閉じると切れる設定(expire_on_close が true)になっていないか確認
Redis / Memcached でセッション管理しているキャッシュ側の最大メモリやキー削除ポリシーで、期限前に消えていないか確認
ロードバランサ配下で不定期に切れるセッションドライバが file のままで、サーバーごとにセッションが分かれていないか確認

現在の設定値は、tinker で確認できます。

php artisan tinker
>>> config('session.lifetime')
=> 480

どのくらいに設定すべきか

有効時間を長くすると「419 エラーで入力が消えた」という苦情は減りますが、ログイン状態も同じだけ長く残るため、共用 PC での乗っ取りなどのリスクが上がります。

  • 一般的な会員サイト・管理画面: 既定の 120 分前後
  • 長文入力や業務システムで離席が多い: 数時間程度に延ばし、下記の対策も併用
  • 金融・個人情報を扱う画面: 短めにし、再認証を求める

有効時間を延ばす以外の対策

期限切れ時に入力内容を残して戻す

Laravel 11 以降では、bootstrap/app.php で 419 エラー時の動作を変えられます。入力値を保持したまま元の画面に戻し、メッセージを表示する例です。

// bootstrap/app.php
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;

->withExceptions(function ($exceptions) {
    $exceptions->render(function (HttpException $e, Request $request) {
        if ($e->getStatusCode() === 419) {
            return back()
                ->withInput($request->except('password', '_token'))
                ->with('error', '一定時間操作がなかったため、もう一度送信してください。');
        }
    });
})

Laravel 10 以前では app/Exceptions/Handler.php で TokenMismatchException を捕捉して同様の処理を書きます。

入力中は定期的にセッションを延長する

長いフォームの画面から、数十分おきに軽い GET リクエストを送るとセッションの期限が延びます。ただし、離席したままでも永久にログイン状態が続くことになるため、用途を限定して使います。

よくある質問

「ログイン状態を保持する」にチェックしていても 419 になるのはなぜ?

ログイン保持(Remember Me)は、セッションとは別の長期間有効なクッキーでログインを復元する仕組みです。セッション自体は期限切れで作り直されるため、古い画面に埋め込まれていた CSRF トークンとは一致せず、419 になります。ログイン保持と CSRF の有効時間は別物と考えてください。

API(routes/api.php)でも有効時間を気にする必要はある?

routes/api.php のルートには標準で CSRF 検証がかからないため、この設定は関係しません。トークン認証(Sanctum など)を使う場合は、そのトークンの有効期限を別途設定します。

関連

Post Share
子ページ

子ページはありません

同階層のページ
  1. インストールと設定
  2. クイックスタート & チュートリアル(初心者向け)
  3. クイックスタート & チュートリアル(中級者向け)
  4. ルーティング
  5. Bladeテンプレート(ビュー/レイアウト)
  6. コントローラー
  7. マイグレーションとテーブル定義
  8. データベースの設定
  9. Eloquentモデル (ORM)
  10. SQLとクエリビルダー
  11. バリデーション
  12. .envファイルの設定値へのアクセス
  13. 動作環境による分岐処理
  14. configフォルダ配下の設定値へのアクセス
  15. assetヘルパーを利用したpublicフォルダへのアクセス
  16. storageフォルダへのアクセス
  17. アプリケーション名の変更
  18. メンテナンス
  19. ログイン画面(認証システム)の作成
  20. ログインの必須化
  21. ログインユーザー情報の取得
  22. ルートの認証化
  23. 本番サーバーへのデプロイ方法
  24. 多言語化
  25. csrf_field
  26. ファイルのダウンロード
  27. CSVのアップロードおよび読み込み(maatwebsite/excel)
  28. ページタイトルの設定
  29. コマンド一覧
  30. エラー一覧
  31. SQLの実行ログ出力方法
  32. キャッシュのクリア
  33. Selectの結果の最初もしくは最後に任意の値を追加する方法
  34. ajaxでPOST通信する際の注意点
  35. ソーシャルログインの実装
  36. セッション情報の確認
  37. ログイン、ユーザー登録、パスワードリセット後のリダイレクト先の変更方法
  38. redirectやreturn viewにメッセージを付与する方法
  39. クッキー(cookie)の設定と取得
  40. クラスの再読み込み
  41. csrfの有効時間を変更する方法
  42. ViewComposerを用いてviewに共通の値を付与する方法
  43. View::shareを用いて共通の値を各ビューに渡す方法
  44. ミドルウェアを用いた処理の共通化
  45. Middleware内でAuth::check()などを使用する方法
  46. Controller以外でリダイレクトする方法
  47. セッションの値の取得/保存/更新/削除
  48. $requestの値を変更する方法
  49. 常時SSL化
  50. ページング(ページネーション)をする方法
  51. vue.jsとの連携
  52. Vue.jsと連携するSPA実行環境構築
  53. .envの値をvue.jsで参照する方法
  54. vue.jsを本番環境にリリースする方法
  55. could not find driver(Windows, MySQL編)