Laravelのbladeで作った画面からPOSTメソッドでフォームを送信したときに
token miss match. 419 Sorry, your session/ 419 your page has expired.
このerrorがでるときがありますよね。
この原因と対策を教えます。
csrf以外で発生するケースの対策も載せてます。
根本の原因はLaravelが持つtokenの値とブラウザがPOSTする_tokenパラメータが一致しないこと
これに尽きるはず。
一致しない、というのはLarabelがデータベースなどのセッションストアに持っている値が変わった後にPOSTすることで一致しなくなる場合もあるし、
何らかの原因でLaravelが参照しているセッションストアと繋げなくなっていても発生します。
なんのことか分からなければ、とりあえず対策を読み進めてください!
@csrfがbladeに無い。またはformの外側になってる
たぶん圧倒的な原因の1位がこれ。
<form method="POST" action="/foo" >
// @csrf
<input type="text" name="name"/><br/>
<input type="submit" value="Add"/>
</form>
bladeのフォームの画面で@csrfディレクティブを入れ忘れていませんか?
または謎にコメントアウトされていたりしませんか?
または次のようにformタグの外側になってませんか?
@csrf
<form method="POST" action="/foo" >
<input type="text" name="name"/><br/>
<input type="submit" value="Add"/>
</form>
これだとフォームから@csrfディレクティブで生成される <input type="hidden" name="_token" value="xxxxx">
のパラメータが送信されません。
この_tokenパラメータが無い状態でPOSTするとLaravelのフレームワークが自動で419 exipred のエラーになります。
このほか、Laravelの細かいけど実践で役立つプログラミングのクイズを作ってみました!
\知識が身に付く、スキルチェックができる!/
単純なセッションの期限切れ
ずっとブラウザの画面を放置したままでPOSTすると419になることがあります。
セッションには有効期限があります。
これが切れていると419errorになります。ブラウザを更新すれば解決します。
laravel5.2以下だと csrf_field()メソッド
@csrfはLaravelのバージョン5.5以上でないと使えないディレクティブです。
その前だとたしかcsrf_filed()メソッドが必要です。古いLaravelを扱っているならこちらを確認しましょう。
ブラウザのキャッシュ?ブラウザの再起動
よく分かりませんが、僕が1度経験した。
ブラウザを再起動したら419が消えたことがありました。
ブラウザの更新でもなく、アプリの再起動でもなく、ブラウザ自体の再起動。
たぶんchromeを使っていたと思います。
セッションストアを変更した?419はキャッシュが残っているせいかも
Laravelではセッションの値の保存先は次のどれかのはず。
fileかdatabaseかredisが多いと思います。
file
– sessions are stored instorage/framework/sessions
.cookie
– sessions are stored in secure, encrypted cookies.database
– sessions are stored in a relational database.memcached
/redis
– sessions are stored in one of these fast, cache based stores.dynamodb
– sessions are stored in AWS DynamoDB.array
– sessions are stored in a PHP array and will not be persisted.
引用元:https://laravel.com/docs/9.x/session#main-content
これを開発中に変更するとconfigのキャッシュが残っているせいで、419エラーになる場合があるみたいです。
php artisan cache:clear
php artisan config:clear
でキャッシュを消してブラウザもリロードして試してみるべし。
あとは、変えたセッションの保存先に値がちゃんと入っているのかを確認すること。
もしfileの人はstorage/framework/sessions以下にセッションファイルがあります。
本番環境で2台のアプリサーバでセッションの保存先がfileの場合
もし本番で冗長化構成で2台以上のアプリケーションサーバがあって、なのにセッションの保存先がローカルのファイルになってたりするとこれは当然発生します。
いまは開発環境で発生している場合を想定るから詳しくは説明しないけど、もし本番で起きているならセッションの保存先をとりあえずdatabaseにすると思います。
【Laravel】エラー。PDOException SQLSTATE[HY000] [2002] No such file or directory