I have a application SPA Vue3 + Quasar and a backend Laravel API, on same domain (localhost), my SPA is on port 8080 and my API on port 80.
In SPA, every time my page refresh, I send a GET to /sanctum/csrf-cookie and them the CSRF Token is stored on browser application cookies.
Also, axios is sending correctly the CSRF token on requisition.
I tried to authenticate with my Laravel API (/login without the /api prefix), at dev environment an then I receive a 419 status code.
I don't know if is important, but my API is running with Sails, on a docker container.
Axios config on Quasar/Vue:
axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://localhost/'
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
Laravel .env
...
APP_URL=http://localhost
...
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8080
cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
Kernel.php,
'api' => [
EnsureFrontendRequestsAreStateful::class,
ThrottleRequests::class . ':api',
SubstituteBindings::class,
],
Cookie Header of my request to /login:
Cookie:
XSRF-TOKEN=eyJpdiI6InJ0SXhRZDVEL21JaEUvL0ptTGdmUlE9PSIsInZhbHVlIjoiU28zenNEQ1VOYTR3NXRVd1JtcU1RaUsvK1BCTHpNUGtUZ3c3T3I0d3lKQjhlZzNjMkVIeDBoOFZWanJDVkw2cWc0RGRDM0NWako0cnN1RXdveThwZkE4dW51aS9Ia1FYVXVsSlpqdW9CK1F3amJTMlFITzhpSCtudDYvY2VpUnUiLCJtYWMiOiIyODkyMzhjYjU5YzMzODY2YTkxZTY3M2MzOWZkNDkwMGQyYjBjNDg0ZTgwMzM3ZDc5NjYwYTcyNWFmZTUyZjExIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6IlQxYXZ4WGhYZGZ5Lzk2WlF5QzJRUHc9PSIsInZhbHVlIjoidE5QQUpaeFh3WWg4cjFJNG82SXNDY1FGUmplWFN5cG5na08zazRmbXFJRFhJVWdUZS81UzJ1RWNaaC84VWxxcTFPdWNuTXd5K0pDaW0zTDliME5BSHl2ZGw4M01lbk1EUDl6SnlVWWFLM2lxNHBTOFBmei9QQXhMaTZLazJSeEEiLCJtYWMiOiIwNjFlNTFkNzIzZTIyZDhjYTg0MmVhMGViMGZjYTU4MmZjY2VmOGMyOWRjODgyNGY3NmE3NjExZDIyYWVhMDU1IiwidGFnIjoiIn0%3D; 3mcV2b1Mp2zT3MoKAWWTOeGlp0TkNFu9FneRzMLK=eyJpdiI6InY1cUYwaXhjdnZlQVRiNDNqaFRMMEE9PSIsInZhbHVlIjoiaE52dVg0dnRYdmE2dDVUT0lUUkJWeXAyaXNkaXMvZkw3RjJwT0hrbkdybUx4K0JyZ2RZV2lMYjEvT3F2TUEvOWQzejkxN05SaHlZMVliUktmUnhVRkwwYTB4cDYzUVB5VFA3MnA5SmlhMmc1Y0VSY3NyMm1JVnd2Vk1XZmFlWU05dEZJWVQrSjFqQ2h6aktFemdFVWZ6cjJBM2MydHNIMlcxRSsvWk1xaDU0Y1RDcHBFUndOL2ZlMXBVWVhyUEQrNS8vOTI5Qmx0TmpMQUtZQ0sxUHZLMEd5MnpGdC91SnVDeDJ5RkF4Tkc0dUphNHhLRFQwUE5Vc0hlR29JaVZqQ3p4Yi9wTFpMUE42UmJOWXoxN0V2bGZlZHduTVRmZUdkcHVnLzBkOWQ0emQyajhjelptSG9XUzRDb3lmZVlpMk5OK1p0R2R2eTdET2FjcTVhVGR4WmRtNVd4ekQ4SHZaeEg3cTUxY0Y2ZVhFdWhJeDh1SUkreUkwdFBmMjErUmdGIiwibWFjIjoiYWVmY2NkY2NiZmJiY2ZhNjkyMTVhODE2MTg0MjkxNTYxZWQ0N2I4NzMyY2RjOWE2NDdiNGY4NjljYjk5NDY0YyIsInRhZyI6IiJ9
Edit:
I discover a new point:
Axios added a header named "Cookie" and inside put the XSRF-TOKEN.. I manually added a header named "X-XSRF-TOKEN" with my cookie which has stored early on Application's Cookies... And finally worked. But I saw in many tutorials this proccess is automatically done by Axios... How can I achieve this?
const login = async () => {
let cookies;
await axios.get("/sanctum/csrf-cookie").then((response) => {
const { get } = useCookies(['XSRF-TOKEN']);
cookies = get('XSRF-TOKEN');
});
axios.defaults.headers['X-XSRF-TOKEN'] = cookies;
await axios.post("/login", form).then((response) => {
console.log(response)
});
}
It's a known issue after Axios 1.6.0
. You have to modify your axios configuration and set withXSRFToken
to true, as below:
axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
Take a look at https://github.com/laravel/docs/pull/9152