LaravelでCSRFエラーのハンドリング

More than 1 year has passed since last update.


エラーページが出るのはダサい:angel::anger:

Laravelに標準で付いてるCSRFチェック機能みなさん使ってますか?

準備が楽かつ便利なのに強力なので、できるだけ使ってWebアプリを実装しましょう。

ただ、デフォルトのエラーページがイケてません。

csrf-error.png

この画面はCSRFアタックを行ったり、長時間フォーム画面で放置してPostした際(セッションタイムアウト)などに表示されます。

さすがに本番環境でデバッグ設定ONにしてる人はいないでしょうが、エラー画面をそのままユーザに見せるわけにはいかないので、CSRFチェックに引っかかった際のエラー処理を実装しましょう。

ちなみに今回対象となるLaravelのバージョンはLTSである5.1になります。5.2と5.3は触っていないので分かりません。ごめんなさい。


処理の流れ

CSRFチェックに引っかかった際は\Illuminate\Session\TokenMismatchException例外が発生します。これをキャッチして何らかの処理を行うといった流れです。

今回は例外をキャッチしたらエラーメッセージ付きでログイン画面に飛ばすといったような処理を実装します。


実装方法

app/Exceptions/Handler.phpを編集します。Handlerクラス内のrenderメソッドを以下のように書き換えます。

public function render($request, Exception $e)

{
// csrf例外だった場合はログイン画面に飛ばす
if ($e instanceof \Illuminate\Session\TokenMismatchException){
session()->flash('csrfError', true);
return redirect()->to(ログイン画面パス);
}

return parent::render($request, $e);
}

これで例外が発生した際はログイン画面に遷移します。

次にエラーメッセージを表示します。以下ログイン画面のビューです。

デザインはよしなにしてください。

@if(session()->has('csrfError'))

<p>お好みのエラーメッセージ</p>
@endif

これで 例外キャッチ->ログイン画面に遷移->エラーメッセージ表示 を実装することができました。