Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

naktoschi's avatar

How to disable CSRF Protection on API Routes when using Passport and JavaScript

Hello,

I have set up Laravel as my backend an am trying to consume my API with JavaScript

Everything is working as expected, I can login and access protected API Routes if I provide the CSRF token. But for development, I'd like to disable CSRF protection entirely, but I don't know how to do this for API routes.

I already added the /api route to the except array in VerifyCsrfToken.php and commented out VerifyCsrfToken middleware in the Kernel.php. This does disable CSRF for web routes, but API routes still need to include the X-CSRF-TOKEN to the request header, because without it, I'm not able to access protected API routes.

0 likes
8 replies
SafeMood's avatar

Hi @naktoschi

u should write in except array in VerifyCsrfToken.php

protected $except = [ 'api/*'];

not only '/api'

1 like
naktoschi's avatar

I've added that route, but that does not work unfortunately. I get the error 401 (Unauthorized).

Just to try it out, I added protected $except = [ '*']; which works on all protected web routes: I don't have to include the CSRF token. But not on API routes unfortunatelly.

naktoschi's avatar

When I remove the auth:api middleware, I can access the route. But I need the auth:api middleware, for example for getting the logged in user. So that is not really an option.

I am sending the laravel_token with every request, so that should not be the problem, and everything works when I include the CSRF token. But I want to get it to work without it.

SafeMood's avatar

Good im not tell removing the auth:api is the solution

but just want to make sure that is not a csrf probleme

so when u use the auth:api u should know

"Laravel includes an authentication guard that will automatically validate API tokens on incoming requests. You only need to specify the auth:api middleware on any route that requires a valid access token"

so u need to send the access token

see docs on how u can create one and how u can pass it in requests

api-authentication

naktoschi's avatar

I understand that I need to create a token. But since I'm using React for my frontend, I don't want to store the token somewhere persistent.

That's why I use the Laravel\Passport\Http\Middleware\CreateFreshApiToken::class middleware, so a laravel_token is sent from the server to the client when logged in. I checked it, and the cookie is successfully set, so that's also not the problem.

That cookie is then sent to the server on every request (that does work too), so that the server should be able to determine if the user is logged in or not. But apparently it is not enough to just send that laravel_token, because without the CSRF token I still get a 401 error. With the CSRF token attached, I can acces routes protected by auth:api

mstrauss's avatar

In Laravel Passport there seems to be a method that allows you to ignore the CSRF check, see below.

https://github.com/laravel/passport/blob/89c81aa8ced151f8e67f47972e1dab71d60e90b4/src/Passport.php#L90

Perhaps setting this to true would solve your issue, so when the below method is called in the TokenGuard class, the CSRF would be bypassed.

    protected function getTokenViaCookie($request)
    {
        // If we need to retrieve the token from the cookie, it'll be encrypted so we must
        // first decrypt the cookie and then attempt to find the token value within the
        // database. If we can't decrypt the value we'll bail out with a null return.
        try {
            $token = $this->decodeJwtTokenCookie($request);
        } catch (Exception $e) {
            return;
        }
        // We will compare the CSRF token in the decoded API token against the CSRF header
        // sent with the request. If they don't match then this request isn't sent from
        // a valid source and we won't authenticate the request for further handling.
        if (! Passport::$ignoreCsrfToken && (! $this->validCsrf($token, $request) ||
            time() >= $token['expiry'])) {
            return;
        }
        return $token;
    }
Snapey's avatar

api routes are stateless and therefore cannot track any issued token

csrf is not required or possible in any of the api.php routes

Please or to participate in this conversation.