【続】CSRF token mismatch.の沼に再びハマりました

この記事はウィルゲート Advent Calendar 2025 8日目の記事です。

adventar.org

こんにちは、ウィルゲート開発室の清水(@takaaki_w)です。

私は昨年のアドベントカレンダーにて、あなたは「CSRF token mismatch.」の沼から抜けられるかという記事を書きました。このときには一度解決していたのですが、その後また同じエラーに悩まされることになりました。

今回は「設定を変更したのに何故かエラーが再発する」という、より深い沼にハマった経験とその解決方法を記します。

前回のおさらい

昨年の記事では、CSRFとは?CSRF tokenとは?について解説していますので、もしまだご覧になっていなければそちらもぜひご確認ください。
また、開発環境で「CSRF token mismatch.」が発生する原因として、.envの下記の設定がコメントアウトされていることを紹介しました。

#SESSION_SECURE_COOKIE=false

これを

SESSION_SECURE_COOKIE=false

とすることで、HTTP環境でもセッションクッキーが正しく送信され、エラーが解消されるというものでした。

今回の問題:設定変更したのに再発

しかし、この設定変更とキャッシュクリアを行った後、しばらくしてから再び「CSRF token mismatch.」が発生するようになりました。

  • .envの設定は正しくSESSION_SECURE_COOKIE=falseになっている
  • php artisan cache:clearなどのキャッシュクリアも実行
  • 開発環境の停止・再起動・再セットアップも実行

それでもエラーが解消せず。。 セキュリティ向上のために人知れず頑張ってくれているCSRF tokenさんに対してまたしても大人気ない態度を取ってしまった私ですが、懺悔の気持ちとして今度こそ「CSRF token mismatch.」の沼から抜ける方法を記します。

解決方法:sessionファイルの削除

最終的に解決した方法は、サーバー上のsessionファイルを削除することでした。

# 1. sessionファイルを削除
rm storage/framework/sessions/*

# 2. キャッシュクリア
php artisan config:clear
php artisan cache:clear

この2ステップを実行したところ、「CSRF token mismatch.」が解消されました。

※この手順はセッションドライバが file(storage/framework/sessions にファイルが保存される設定)の場合に有効です。redis や database を使っている場合はそれぞれのクリア方法を確認してください。

なぜsessionファイルの削除が必要だったのか

ここからが本題です。なぜ設定を変更しただけでは不十分で、sessionファイルの削除が必要だったのでしょうか。

LaravelのCSRF token検証の仕組み

まず、LaravelのCSRF保護の仕組みをおさらいします。

公式ドキュメントによると、

Laravelは、アプリケーションによって管理されているアクティブなユーザーセッションごとにCSRF「トークン」を自動的に生成します。このトークンは、認証済みユーザーが実際にアプリケーションへリクエストを行っているユーザーであることを確認するために使用されます。このトークンはユーザーのセッションに保存され、セッションが再生成されるたびに変更されるため、悪意のあるアプリケーションはこのトークンへアクセスできません。

引用:https://laravel.com/docs/11.x/csrf

readouble.com

つまり、CSRF tokenはセッションに保存され、リクエストのたびにこのtokenが検証されます。

問題の本質

ここで重要なのは、セッションデータはstorage/framework/sessionsディレクトリにファイルとして保存されているということです。

私が遭遇した問題の流れはこうでした:

  1. 当初の状態

    • .envSESSION_SECURE_COOKIE がコメントアウトされており、デフォルトでは true
    • この状態で開発環境(HTTP)にアクセス
    • LaravelはセッションCookieに Secure 属性を付与
      → HTTP通信ではこのCookieが送信されない
    • 結果として、毎回新しいセッションが生成される
  2. 設定変更後

    • .env にて SESSION_SECURE_COOKIE=false に変更
    • php artisan config:clear を実行して設定キャッシュをクリア
    • しかし、既存のセッションファイルは削除されず
      さらにブラウザには古い Secure 属性付きCookieが残っていた
  3. 再度エラーが発生した原因

    • HTTP環境では古いCookieが送信されず、サーバーは新しいセッションを生成
    • 一方で、サーバー側には古いセッションファイルが残っており、整合性が取れない
    • 結果として、CSRFトークンが一致せず「CSRF token mismatch.」が発生

キャッシュクリアだけでは不十分な理由

php artisan config:clearphp artisan cache:clearではsessionファイルは削除されないということです。

php artisan config:clear  # 設定キャッシュのみクリア
php artisan cache:clear   # アプリケーションキャッシュのみクリア

これらのコマンドは、それぞれ

  • bootstrap/cache/config.php
  • storage/framework/cache

をクリアするだけで、storage/framework/sessionsには影響しません。

そのため、設定を変更した場合は明示的にsessionファイルを削除する必要がありました。

これから/おわりに

昨年の記事で解決できなかった方、すみません。 ぜひこちらの記事もお試しいただき、感想など教えていただけたら嬉しいです。

ウィルゲート Advent Calendar 2025」、翌日は吉田さんの「PdM視点で振り返る、CI × E2Eテストがもたらしたチームの変化」です! お楽しみに!