Wow it looks like I'm not the only having problems to configure correctly sanctum to be working fine with VueJS / axios.
But here your problem is with Postman, isn't it ?
Have you checked if the cookie is set in the browser ?
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I have followed the instructions and set it all up https://laravel.com/docs/9.x/sanctum#how-it-works
POSTMAN is setting cookie in the headers but it's not actually being set?! I have added
axios.defaults.withCredentials = true;
to my vue app
Cookies are just not getting set?! Please help
Wow it looks like I'm not the only having problems to configure correctly sanctum to be working fine with VueJS / axios.
But here your problem is with Postman, isn't it ?
Have you checked if the cookie is set in the browser ?
so initially it was working ok with POSTMAN, browser. has never worked
@boyjarv Ok so you are trying to configure it to have it working with a browser.
I had to set correctly the domains in the .env file.
SESSION_DOMAIN and SANCTUM_STATEFUL_DOMAINS
What is your code to initiate the login from the front ?
this is my Login method where the cookie should be set:
public function login(Request $request) {
if (!\Auth::attempt($request->only('email', 'password'))) {
return response([
'error' => 'invalid credentials'
], Response::HTTP_UNAUTHORIZED);
}
$user = \Auth::user();
$adminLogin = $request->path() === 'api/admin/login';
if($adminLogin && !$user->is_admin) {
return response([
'error' => 'Access Denied!'
], Response::HTTP_UNAUTHORIZED);
}
$scope = $adminLogin ? 'admin' : 'ambassador';
$jwt = $user->createToken('token', [$scope])->plainTextToken;
$cookie = \Cookie::make('jwt', $jwt, 60*24); //1 day
return response([
'message'=> 'success'
])->withCookie($cookie);
}
@boyjarv You have customized the authentication system, are you sure to respect the Laravel authentication system ?
I use Fortify to manage the authentication, I've never tried to write my own authentication system.
And I see that you are creating a token for the user. Why do you need it ?
When I tried to understand how Sanctum is working, I also created a token, but it is not necessary because Sanctum does it for you. Unless you really need one.
How are you calling your login API ? I mean the VueJS / React / ... code ?
in my Vue app main.ts
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
import axios from 'axios'
axios.defaults.baseURL = 'http://laravel-ambassador.test/api/admin/';
axios.defaults.withCredentials = true;
Vue.config.productionTip = false
new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app')
config/session.php
domain' => env('SESSION_DOMAIN', env('APP_URL')),
config/sanctum.php
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,laravel-ambassador.test'
)),
.env
SESSION_DRIVER=file
SESSION_SECURE_COOKIE=false
SESSION_DOMAIN=laravel-ambassador.test
SANCTUM_STATEFUL_DOMAINS=laravel-ambassador.test,http://localhost:8080
@boyjarv I'm not sure because I'm yet learning around Sanctum. I have problem too ;).
Try this.
SESSION_DOMAIN=laravel-ambassador.test,localhost:8080
SANCTUM_STATEFUL_DOMAINS=laravel-ambassador.test,localhost:8080
You don't need to add the domain route in the sanctum configuration file, you already add it via the .env file.
@boyjarv I didn't notice first, but the session driver has to be cookie and not file.
SESSION_DRIVER=cookie
But for me it doesn't work better, even with cookie it doesn't work.
and my Vue login file:
<template>
<main class="form-signin w-100 m-auto">
<form @submit.prevent="submit">
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
<div class="form-floating">
<input
v-model="email"
type="email"
class="form-control"
placeholder="[email protected]"
/>
<label>Email address</label>
</div>
<div class="form-floating">
<input
v-model="password"
type="password"
class="form-control"
placeholder="Password"
/>
<label>Password</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">
Sign in
</button>
</form>
</main>
</template>
<script>
import axios from 'axios'
export default {
name: "Login",
data() {
return {
email: '',
password: ''
}
},
methods: {
async submit() {
await axios.post('login', {
email: this.email,
password: this.password,
}, {withCredentials: true});
await this.$router.push('/');
}
}
};
</script>
<style scoped>
.form-signin {
max-width: 330px;
padding: 15px;
}
.form-signin .form-floating:focus-within {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
</style>
@boyjarv Do you have a 419 error ?
@vincent15000 I have 419 error and i am not being able to solve it what ever i do. I am using react front end and laravel breeze api authentication system.
@Ganesh Adhikari Create a new thread instead adding reply on older threads. This helps moderator to answer quickly.
no a 401 because my cookie is not being set in the browser and therefore I'm unauthorised
@boyjarv See my recent post about this problem. Perhaps you can participate ;).
https://laracasts.com/discuss/channels/code-review/laravel-sanctum-vuejs-axios-error-401
@boyjarv it should be
SESSION_SECURE_COOKIE=true
@sos99 Thanks but that didn't make things any better
@boyjarv Can you try this. It just worked for me.
For me the front and the back are on the same domain, but on different subdomains.
In this case, the SESSION_DOMAIN has to be defined with a dot (as if there were a wildcard).
SESSION_DOMAIN=.mydomain.com
nope that didn't work
would it be something to do with my CORS blocker or the fact I am using Laravel valet?
@boyjarv For Laravel Valet, I don't know. Something to do with the CORS, I don't think so, you would have an explicit error in the network development tools on the browser.
Do you really need to customize the authentication system ?
@vincent15000 I'd like to be able to set the cookie in teh browser and login
@boyjarv Ok so you don't really need to customize the authentication system.
I think that I have understood how to do. Don't overwrite the login function in your controller. Just use the Laravel authentication system. I use Fortify and it's just magic for me. But you can also use another package like Breeze for example.
Once you have installed the authentication system, you can test it adding a simple form in your back, so you are sure it works.
Then you have to install Sanctum (unless you are using Laravel 9 where it is already included).
All is very simple, but in fact I took 2 weeks to solve my different issues (fortunately I have sleeped and worked on other projects at the same time) ;).
Once you have sanctum installed, you just have to set it up correctly.
// sanctum.php
// nothing to change
// cors.php
// all routes for which you want that Laravel don't block with CORS error
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],
...
'supports_credentials' => true,
// session.php
// nothing to change
// .env
SESSION_DRIVER=cookie
SESSION_DOMAIN=.yourdomain.com // notice the dot
SANCTUM_STATEFUL_DOMAINS=subdomain_that_access_the_api.yourdomain.com // frontend URL
// bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.withCredentials = true;
Then in the front end code, you have to configure axios.
const api = axios.create({
baseURL: 'http://your_api_subdomain.yourdomain.com',
withCredentials: true
})
And you can use api to access your API.
async login(user) {
await api.get('/sanctum/csrf-cookie') // first you retrieve the CSRF token
await api.post('/login', { email: user.email, password: user.password }) // then you login via the login route
return // what you want here ;)
}
Then you can access any other API route
api.get('/api/my_super_route')
I hope I have not forgotten anything ;).
@vincent15000 Thanks, done all that , I get: GET http://laravel-ambassador.test/api/admin/sanctum/csrf-cookie 404 (Not Found)
am I supposed to setup a route in my api folder to /sanctum/csrf-cookie ?
@boyjarv By default this route is at the root of your domain.
http://laravel-ambassador.test/sanctum/csrf-cookie
You can find it by displaying the routes.
php artisan route:list
@vincent15000 now I'm getting 419 error
@boyjarv That's a CSRF error. For which API call do you get this error ?
@boyjarv Hello, have you solved your problem ?
Hey @boyjarv did you solve the 419 error? I'm now getting it.
Please or to participate in this conversation.