Laravel provides CSRF protection out of the box on all your application routes. Sometime you may want to exclude some of the routes from CSRF protection check.

What is CSRF?

A Cross Site Request Forgery is an attack that tricks a web browser into executing an unwanted action in an application to which a user is logged in.

CSRF is also known as XSRF, Sea Surf, and Session Riding.

A successful CSRF attack can be devastating for both the website owner and the end user. It can result in unauthorized fund transfers, password change, and personal data theft. In a CSRF attack, unauthorized commands are performed on behalf of an authenticated user.

How Laravel handles CSRF

In Laravel, there is a middleware class Illuminate\Foundation\Http\Middleware\VerifyCsrfToken with a method handle(), which gets executed on every HTTP request.

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 *
 * @throws \Illuminate\Session\TokenMismatchException
 */
public function handle($request, Closure $next)
{
    if (
        $this->isReading($request) ||
        $this->runningUnitTests() ||
        $this->inExceptArray($request) ||
        $this->tokensMatch($request)
    ) {
        return tap($next($request), function ($response) use ($request) {
            if ($this->shouldAddXsrfTokenCookie()) {
                $this->addCookieToResponse($request, $response);
            }
        });
    }

    throw new TokenMismatchException('CSRF token mismatch.');
}

In the VerifyCsrfToken class's handle() method, we can see that unless $this->isReading($request) or $this->tokensMatch($request) return true, a TokenMismatchException exception will be thrown.

The isReading($request) method simply look for reading verbs like HEAD, GET and OPTIONS.

/**
 * Determine if the HTTP request uses a ‘read’ verb.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return bool
 */
protected function isReading($request)
{
    return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
}

If one of these being used in the request, it will skip over the CSRF check. The whole idea of using CSRF is meant to prevent other websites from submitting POST form data, so we can neglect the GET requests.

If the isReading($request) return false, it will call the tokenMatch($request) method. This does the work of actually deciding whether a token was included in the request, and if so, checks whether or not it matches the one stored in the session.

Within the same VerifyCsrfToken class, we can also find an array property called $except.

/**
 * The URIs that should be excluded from CSRF verification.
 *
 * @var array
 */
protected $except = [];

As you can see from the class comments, you can pass the URIs to this array if you want to exclude some routes from this CSRF check.

Disabling CSRF on specific routes

Now, if we open the App\Http\Middleware\VerifyCsrfToken class, we can see that this class simply extends the Illuminate\Foundation\Http\Middleware\VerifyCsrfToken class thus provide the access to $except property.

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        //
    ];
}

Simply add your routes inside that array which you want to exclude from the CSRF protection.