#CSRF Token Mismatch Error and Cookie Issue in Laravel Project on Local Machine

31 messages · Page 1 of 1 (latest)

plain flume
#

Description

I'm encountering a CSRF token mismatch error in my Laravel application, specifically in one project on my local machine. The error occurs consistently and prevents API requests from being processed, leading to exceptions across the application. Notably, no cookies, including the CSRF token and Laravel's default cookies, are being set in the browser.

Environment Details

Laravel Version: 8.83
PHP Version: 8.1.27

Steps Taken

  • Verified the .env file for correctness.
  • Checked and ensured proper permissions for the storage/framework/session and storage/framework/cache directories.
  • Confirmed that system configurations match with the production environment.

Expected Behavior

The application should set the necessary cookies, including the CSRF token, and process API requests without encountering CSRF token mismatch errors.

Additional Notes

This issue is specific to my local machine and does not occur in the production environment or on other devices.
No recent changes were made to the codebase that could directly cause this issue.

versed wing
#

On which domain is your frontend and which domain is your api? They'd need to be on the same domain (or a sub-domain) for it to work.

plain flume
#

Frontend and backend both are in the same domain. I'm just using CDN in the blade files and making network request through it. @versed wing

versed wing
#

Sorry, no clue what that means

plain flume
#

I mean to say, The view part is VUEJS instead of blade and API is Laravel.

versed wing
#

And you're using Sanctum?

plain flume
#

No, I'm not using Sanctum.

versed wing
#

Then what are you using? Since Sanctum is built to deal with this

plain flume
#

Honestly the itself app is a mess.

"The frontend and backend is sharing the same session and it take cares of authentication"

My manager told me this.

There is no api route inside the api.php All routes are listed in the web.php
Both routes share the same auth middleware

#

During inspection, I noticed the the csrf token attached in the axios request and token extracted from the session are different.

This same code is in production and working fine.

versed wing
#

Ah right, so your routes being in web is good then (guess it's more of a legacy thing in your case, prior to Sanctum existing, so using the web routes would be a good approach to provide session)

#

On which domains do the apps run? Local and prod. Might be that locally your cookie is actually blocked or not set, you might have an old cookie that's just present

plain flume
#

The prod is working fine. It even worked on my linux laptop but not on macbook. Both of them have same system configuration.

I tried running other laravel applications with same version, they have also worked.

I have tried couple of browser with no success.

There is no header Set-Cookie.

pseudo valve
#

Are you serving it via https (not http) locally?

#

Also make sure you haven't modified vendor code by mistake, rm -rf vendor && composer install

plain flume
#

I'm serving it using http locally. I did remove the vendor and installed packages again with no success.

When I dig deeper, I found the token generated by csrf_token() function is different than $request->session()->token() in the VerifyCsrfMiddleware.php.

pseudo valve
#

I suppose you don't have session.secure set (as that would skip cookies in a http-context)?

#

If you don't have any cookies, the tokens are definitely going to be different since it's randomly generated again for each request

plain flume
#

Yes, session.secure is default value.

The thing is, it's working fine on other machine. It's the most frustrating part

pseudo valve
#

Double check in running app that session.secure is not overwritten by an env variable for some reason

#

Did you verify that no cookies are returned from the server? If they are returned, but doesn't "stick", there is usually information about why in the Chrome dev tools

plain flume
pseudo valve
#

I should be next to the "Set-Cookie" header in the response section of the network tab.

plain flume
#

I already checked that. There is not Set-Cookie header.

I logged the value of $response->headers->getCookies(); from Illuminate\Foundation\Http\Middleware\VerifyCsrfToken class.

 array (
  0 => 
  Symfony\Component\HttpFoundation\Cookie::__set_state(array(
     'name' => 'XSRF-TOKEN',
     'value' => 'yEAOuKryHKfadSLXF9pjOTEi5jSwfV85h5EQAYSY',
     'domain' => NULL,
     'expire' => 1714030802,
     'path' => '/',
     'secure' => NULL,
     'httpOnly' => false,
     'raw' => false,
     'sameSite' => 'lax',
     'secureDefault' => false,
  )),
)  

This was the output. I have also checked this with domain as localhost but still same error

pseudo valve
#

How is the local server running – with php artisan serve or something else?

plain flume
#

Yes php artisan serve is running the server.

pseudo valve
#

Is the dump above old? The expiration time is 9 hours ago.

I really don't have any idea why cookie headers are not returned. I'm very curious to understand why.

plain flume
pseudo valve
#

One other wild guess – in php headers can't be set after output has started to be sent. A leading whitespace in any of the php files could cause that. It would also show as a warning in fpm-logs, so check that, or search for <?php or \n<?php

plain flume
pseudo valve
#

I had one unexpected problem with environment variables with Herd, but I could see that in the config at runtime. I had to update the variables_order php ini setting.