Reputation: 29
I'm trying to learn and build a backend using Laravel 12, it comes with inertia that allows me to manage my auth tokens and CSRF token for a React app, but based on my understanding it's for the React app that is in tandem already with that laravel app.
I have my own separate React app in which I want to call the APIs from. So what I'm trying to do is call some auth APIs in Laravel backend specifically the '/register'
but it requires me to have CSRF token.
So I tried to start session by hitting a get request on '/'
, this will give me XSRF cookie in my frontend. I was able to get those cookie but then when I hit a request again on '/register'
, the XSRF token is present but in cookies and not in the actual header of the request and this will give me error of "message: CSRF token mismatch.".
Response header for getting token looks like this:
access-control-expose-headers:
XSRF-TOKEN
cache-control:
no-cache, private
connection:
close
content-type:
text/html; charset=UTF-8
date:
Sun, 02 Mar 2025 07:59:55 GMT
host:
127.0.0.1:8000
link:
<http://127.0.0.1:8000/build/assets/app-wKvlsDeH.css>; rel="preload"; as="style", <http://127.0.0.1:8000/build/assets/app-0LmJ1Xg0.js>; rel="modulepreload", <http://127.0.0.1:8000/build/assets/welcome-CmFPhQLK.js>; rel="modulepreload"
set-cookie:
XSRF-TOKEN=eyJpdiI6InNHRFowZnVNSkoyUjZNN2R4Q3JpRHc9PSIsInZhbHVlIjoiQ0V2d0JsZDI4U0tGY0I0WkNnM0tzVnkwRWJNYmJNZWp5ZEx2bTZHRzUvZE81Y1JjZ0FzdXNFenM0citzUFJjcmV3bk1MZ2FaYjFqYTBBTFhzbWNabDMyalBkOFg1UTcxb1p3MlhWTllLWThHVE1DSVJRTVJ2WTRlTUhVazI5V2oiLCJtYWMiOiI4MzkyODVhMmNmYzAzMzYyYTNmNzRjZThjZDZiNjFlNTRhNDc3NDQ0OWZmZmVmOWNhMmQxNzg3MjAxOGM4NDM1IiwidGFnIjoiIn0%3D; expires=Sun, 02 Mar 2025 09:59:55 GMT; Max-Age=7200; path=/; secure; samesite=none
set-cookie:
laravel_session=eyJpdiI6IkluY1hPRFFNWE52V3JpbTFCRmVyZVE9PSIsInZhbHVlIjoiOHduT3BZWWFza3pvdCt6K2ZLOFBnSG1UVVN2dVJNTUZiRHhYeUFDNld1WWlvNWZOQjRGMU80MlIzZk1uTjVVb2hEdytWNEtMYkJjYmlvdmdPTjJYL3JhQWZTWmc4MXlJMWg5RVBjN1NFTXMwU2ZKZlBLZkEyZ2owUzJtVW5JMlkiLCJtYWMiOiI3N2Y0MzYzMTQxNTU5MzdmODY3MDY5N2U1NGRjODA4MGUzOTQ4N2Y0MTAwMWNmY2E1MTI5MDIwYzIxNTIwMzQwIiwidGFnIjoiIn0%3D; expires=Sun, 02 Mar 2025 09:59:55 GMT; Max-Age=7200; path=/; secure; httponly; samesite=none
Request header for /register looks like this:
cookie:
XSRF-TOKEN=eyJpdiI6IlM3SW5FMU5LOXV1emp1ckhvcWpFb1E9PSIsInZhbHVlIjoiWXhaaHFDQlRWdG5YclVHY2dJeUppY0ZtNlNENHdGblExbWc5VnJhNGQ1QW1FejVBMzZUOVJCSXNibFJ2Slc5QzNrMGo5RW9WVWpXOU55NmNta2N1cjl4dWxBcTlPT2tib3R1blhIV1hvdVdIaVBaM215ejRockNKTmc5b0RnSnQiLCJtYWMiOiJhMzBiNWRhYTliZWU4M2QyYTY2YTgxYzU3NTE3MTNhMzA5Y2U1ZmJkZWU0Mzg4MjQ2NGY0MjgzOTlkM2ZkNGY4IiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6Ikpwd0hwZnh1ZmM4d29mUHhKdXNnNUE9PSIsInZhbHVlIjoiNW5EWHpUMElQQWRPc3RLVGRUVndkUnRNZFBrWUtDYTV0eUU4RXYvUFhpRzU2VmN5dGtIaitxUU41dGZ6ODYyWDVRMDlDbGpTSFhGYi95Vmk5UDU4QklXK05jUFBVZTVaSkRWVlRFMFByVUE5Vmt5S0Q3UmwzZzE5ZHpRYk9jU2MiLCJtYWMiOiI0YmZiNWI1ZjY5ZjExZmIxN2FjYjhhZWQwNzc5NjQwNjc2OTBmNDVjOWYxZjU5YWZmZjE3NTcwNDBkZGM0MDc4IiwidGFnIjoiIn0%3D
host:
127.0.0.1:8000
origin:
http://localhost:3000
I think this should have XSRF-TOKEN variable also in header to be successful. What am I doing wrong in here?
const axiosInstance: AxiosInstance = axios.create({
baseURL: 'http://127.0.0.1:8000',
withXSRFToken: true,
withCredentials: true,
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
})
Upvotes: 0
Views: 53
Reputation: 265
If you are trying to accomplish this with SPA, Laravel sanctum will do the trick.
Before calling the /register
endpoint, you should call the /sanctum/csrf-cookie
and point so that your request will automatically have the necessary cookies.
Make sure that you also have your backend properly configured to make it SPA enabled.
So your axios call might look like this.
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/api/register', {
email: email,
password: password
}).then(response => {
console.log(response)
})
})
Hope this helps.
Upvotes: 0
Reputation: 51
I don’t fully understand your question, but since your frontend and backend are separate, I suggest using token-based authentication (JWT, Sanctum, or Passport) instead of session-based authentication.
If you’re using a token-based approach, you don’t need CSRF protection, because CSRF attacks rely on cookies, and tokens are sent via headers.
However, if you still want to disable CSRF checks for specific routes in Laravel, you can exclude them in bootstrap/app.php
:
...
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'register',
]);
})
Note: Only disable CSRF checks for specific API routes that do not rely on cookies. Disabling it globally can be a security risk.
Upvotes: 0
Reputation: 19
You need first to store token in meta tag or somewhere else and when doing the request you need to send it as specific header. Read the documentation here, https://laravel.com/docs/12.x/csrf#csrf-x-csrf-token
Correct header is "X-CSRF-TOKEN"
Upvotes: 0