Catch TokenMismatchException thrown by VerifyCsrfToken in Laravel

Reading Time: 2 minutes

If you are using Laravel 5, you must have come across something like this when a form wasn’t after a long period of time of opening the page.

 

This was meant to help with checking against CSRF but it can be really annoying seeing this. Most of your user/visitors don’t understand the gibberish written, and you can’t possibly tell them to always submit the forms on time. No, you just can’t. Neither should you assume that they will only be visiting your website/app at the time they are on the page.

Solution

Don’t disable the CSRF verification on your site. DON’T!

You can just simply catch this error and do something with it (well, not literarily).

Let me show you how you can catch the error and possible display the form again.

  1. Open app/Exceptions/Handler.php
  2. Find the render() method
  3. Add this piece of code to it

     

    if ($exception instanceof TokenMismatchException){
        //redirect to a form. Here is an example of how I handle mine
        return redirect($request->fullUrl())->with('flash-msg', 'Oops! Seems you didn\'t submit form for a longtime. Please try again.');
    }
  4. So your render method should now look like this

     

    /**
     * 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)
    {
        if ($exception instanceof TokenMismatchException){
            //redirect to a form. Here is an example of how I handle mine
            return redirect($request->fullUrl())->with('flash-msg', 'Oops! Seems you didn\'t submit form for a longtime. Please try again.');
        }
        return parent::render($request, $exception);
    }

You can decide to do something else instead of redirecting to the original form.

That, my friend, is how to overcome the ugly TokenMismatchException in VerifyCsrfToken.php without compromising your site’s security.

Update

If you cannot find the render() method, go to vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php

Copy the render() method and paste it in app/Exceptions/Handler.php

Replace $exception with $e

So your final render() method in app/Exceptions/Handler.php will look like this

public function render($request, Throwable $e)
    {
        if (method_exists($e, 'render') && $response = $e->render($request)) {
            return Router::toResponse($request, $response);
        } elseif ($e instanceof Responsable) {
            return $e->toResponse($request);
        }

        $e = $this->prepareException($this->mapException($e));

        foreach ($this->renderCallbacks as $renderCallback) {
            if (is_a($e, $this->firstClosureParameterType($renderCallback))) {
                $response = $renderCallback($e, $request);

                if (! is_null($response)) {
                    return $response;
                }
            }
        }

        if ($e instanceof HttpResponseException) {
            return $e->getResponse();
        } elseif ($e instanceof AuthenticationException) {
            return $this->unauthenticated($request, $e);
        } elseif ($e instanceof ValidationException) {
            return $this->convertValidationExceptionToResponse($e, $request);
        } elseif ($e instanceof TokenMismatchException){
            return redirect($request->fullUrl());
        }

        return $request->expectsJson()
            ? $this->prepareJsonResponse($request, $e)
            : $this->prepareResponse($request, $e);
    }