November 15, 2015 23:56

CSRF tokens are great for security but there are rare occurrences where the token is invalid when it shouldn't be.

An invalid token is usually a temporary problem* - it's solved immediately on the next page load when their new session is created and token is refreshed. So it's bad UX to simply throw an exception and display a useless page or worse, a nasty error page.

*One case in which it wouldn't be temporary is if sessions aren't working properly at all; for example, if you're using the file session driver but your server is out of disk space or the folder isn't writeable.

A simple solution to this is to catch those exceptions and tell the user to "try again." Now it's just a slight annoyance to your user and not something that will completely stop them in their tracks. Modifying your handler like this takes care of that:

use Illuminate\Session\TokenMismatchException;

class VerifyCsrfToken extends BaseVerifier {
    public function handle($request, Closure $next)
        try {
            return parent::handle($request, $next);
        } catch (TokenMismatchException $e) {
            if ($request->ajax()) {
                return response('CSRF error', 500);

            return redirect()->back()
                ->withErrors(['Something went wrong, please try again']);