LoginSignup
66
42

More than 3 years have passed since last update.

【Laravel5】たまに出てくる「the page has expired due to inactivity. please refresh and try again」を表示させない

Last updated at Posted at 2019-07-19

多くの原因はCSRFトークンを記述していない場合で発生する

ググってみると多くの場合はフォーム内にCSRFトークンの記述漏れで発生していることが多いようです。
なのでまずはフォーム内にCSRFトークンの記述があるかを確認してください
Laravel5.6以前なら{{ csrf_field() }}を、
Laravel5.6系以降なら@csrfというシンプルに記述できるので、これをフォーム内に埋め込んでください。

以下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>

以下参考になるのかもしれませんが少し情報が古いので注意
【Laravel】TokenMismatchExceptionが発生する原因 - Qiita

CSRFトークンの有効期限切れで表示される

CSRFトークンの有効期限切れで表示される場合(例えばログイン画面で長時間放置してからログインしたりする
以下のような画面が表示され、リロードしろと促されます。

419.png

正直、この画面がでても何のことかわからないし、あまりにも突然表示されたりするので、
CSRFトークンが有効期限切れの状態でログインしたりした際、ログイン画面へリダイレクトさせる処理app/Exceptions/Handler.phpに記述していきます。

laravel\app\Exceptions\Handler.php
<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Session\TokenMismatchException; // add
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{

// ...

    /**
     * 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)
    {
        // 「the page has expired due to inactivity. please refresh and try again」を表示させない
        if ($exception instanceof TokenMismatchException) {
            return redirect('/login')->with('message', 'セッションの有効期限が切れました。再度ログインしてください。');
        }

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

これでTokenMismatchExceptionが発生した場合はログイン画面へエラーメッセージとともにリダイレクトさせることができる

ステータスコード(419)の場合にリダイレクトさせる

ちなみにステータスコードで判定するようにもできるので以下のようにも書けます。

laravel\app\Exceptions\Handler.php
<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\ViewErrorBag; // add
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; // add

class Handler extends ExceptionHandler
{

// ...

    /**
     * Render the given HttpException.
     *
     * @param  \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface  $e
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function renderHttpException(HttpExceptionInterface $e)
    {
        $this->registerErrorViewPaths();

        // 「the page has expired due to inactivity. please refresh and try again」を表示させない
        if ($e->getStatusCode() === 419) {
            return redirect('/login');
        }

        if (view()->exists($view = "errors::{$e->getStatusCode()}")) {
            return response()->view($view, [
                'errors' => new ViewErrorBag,
                'exception' => $e,
            ], $e->getStatusCode(), $e->getHeaders());
        }

        return $this->convertExceptionToResponse($e);
    }

}

ただステータスコード419が必ずしもCSRFトークンの有効期限切れで返しているかわからないので、TokenMismatchExceptionが発生した場合のみログイン画面へリダイレクトさせた方がいいかなと思っていますがどうでしょう?

おわり

  • もっといい方法あれば教えていただきたいです草々不一

参考URL

66
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
66
42