Edited at

【Laravel】TokenMismatchExceptionが発生する原因


TokenMismatchExceptionが発生する原因

フォーム等でPOSTをする際、Laravel が発行するCSRFトークンが必要で、

そのトークンがないと表題のTokenMismatchExceptionが発生するようになります。

(詳しくはリーダブル参照: CSRF保護 5.4 Laravel

以下のコードをブレードのformタグ内に埋め込む必要があります。


blade.php

{{ csrf_field() }}


以下Laravel5.6以前の記述例


form.blade.php

<form method="POST" action="/profile">

{{ csrf_field() }}
...
</form>

以下Laravel5.6系以降の記述例


form.blade.php

<form method="POST" action="/profile">

@csrf
...
</form>

HTMLのソースでは↓のように表示されます

<input type="hidden" name="_token" value="DC83jdkaHfAlskdjvskjiSVHEcrvzNK2fjcjpa3s*****">

逆に言うとTokenMismatchExceptionが発生する場合、作成したフォーム要素内にCSRFトークンが埋め込まれてない可能性大です


TokenMismatchException発生時の挙動制御

\app\Exceptions\Handler.phprenderメソッドで挙動を制御できます。


Handler.php

/**

* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/

public function render($request, Exception $exception)
{
// TokenMismatchException発生時
if ($exception instanceof TokenMismatchException) {
// TokenMismatchException発生時はindexへリダイレクトさせる
return redirect('/index');
}
return parent::render($request, $exception);
}

設定したことを忘れないようにしてください。

(403エラーページなどに飛ばした方がいいのかもしれません。)


有効期限

defaultで120分(2時間)みたいです。


config/session.php

    /*

|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/

'lifetime' => 120,

'expire_on_close' => false,