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

sididev's avatar

Laravel Sanctum SPA Authentication Issue with Vue 3 and Axios

Hi there, I'm encountering a problem that I can't seem to solve after a few days of research. I have a Vue 3 Pinia front-end application in a /vue-cli/queneadmin directory, which is on the port: http://localhost:5173. The back-end is with Laravel Breeze API (sanctum) at /project/quenea, running on the port: http://quenea.test (using Laravel Valet for the project name .test). When I try to test my login, I get an error: POST http://quenea.test/login 419 (unknown status), but when I check the Network, csrf-cookie is 204 and /login is 419. However, when I look in the Application tab, I don't see any cookies..

In my .env configuration, I've done what's necessary as Laravel Breeze has correctly configured the cors.php with credentials set to true.

APP_URL=http://quenea.test
FRONTEND_URL=http://localhost:5173
SESSION_DOMAIN=quenea.test
SANCTUM_STATEFUL_DOMAINS=localhost:5173
SESSION_DRIVER=cookie

Here's my axios config:

import axios from 'axios';

axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
axios.defaults.baseURL = 'http://quenea.test';

export default axios;

This is my authService.js:

import axios from './axiosConfig';

export const authService = {
    async getCsrfCookie() {
        await axios.get('/sanctum/csrf-cookie');
    },

    async login(credentials) {
        await this.getCsrfCookie();
        return axios.post(`/login`, credentials);
    },
....

And my auth store:

...
async login(credentials) {
  try {
    const response = await authService.login(credentials);
    console.log(response)
    // this.user = response.data.user;
  } catch (error) {
    this.error = error.response.data.message;
  }
},			
...

Finally, my LoginView:

...
const authStore = useAuthStore();

const credentials = reactive({
  email: 'test@test',
  password: 'password'
})

const error = ref('');

const login = async () => {
  await authStore.login(credentials);
  error.value = authStore.error;
};
0 likes
2 replies
sididev's avatar
sididev
OP
Best Answer
Level 8

Hi there i saw this on laravel docs

" In order to authenticate, your SPA and API must share the same top-level domain. However, they may be placed on different subdomains. Additionally, you should ensure that you send the Accept: application/json header and either the Referer or Origin header with your request. "

So this means localhost and quenea.test are not on the same top level domain I changed .env and run php artisan serve

APP_URL=http://localhost:8000
SESSION_DOMAIN=localhost

Btw, if I wanted to use quenea.test, I had to create a valet for the vue project and run it on spa.quenea.test

More if u want to use different domain u can check this link : https://www.youtube.com/watch?v=gKC7yvllsPE very helpfull

Thxx

2 likes
sididev's avatar

For those who don't want to watch the video, although I recommend it, especially for different domains, it explains more with more examples than what you will see here...

😩 I've also noticed a slight disorder in the network tap, and some requests are taking a bit longer than expected.

Soo for different domains:

We will create an intermediary layer between our API and Vue 3, which is the proxy. In my case, I'm using Vite with Vue 3, so my proxy configuration is done in the vite.config.js file. You should add the following:

server: {
        proxy: {
            '/api': {
                target: 'http://quenea.test',
                changeOrigin: true,
                rewrite: (path) => path.replace(/^\/api/, '')
            },
        }
    }

And in the Axios configuration, instead of using http://quenea.test, we will use /api:

import axios from 'axios';

axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;
axios.defaults.baseURL = '/api/';

export default axios;

Finally, the browser should choose the host as the cookie domain, so in the .env file, we should remove:

// remove this
SESSION_DOMAIN=quenea.test

šŸŽ‰šŸŽ‰šŸŽ‰

1 like

Please or to participate in this conversation.