I believe that I’m completely lost of reading n articles & documentations and not sure what is the right way of using Sanctum. Just a heads up what I’m trying to reach/create before talking more about the issue. I want to build an application which will communicate only via API, basically via tokens. For that my back-end will be created with Laravel and front-end with Nuxt3. I think that most of my Laravel setup is correct, but the whole workflow is incorrect, the issue is now that after log in from Nuxt application I successfully receive user data and token. However, when I’m trying to enter protected endpoint with auth:sanctum – I receive 401 (Unauthorized). However, if I manually attach the Bearer token to request – everything is fine and that makes sense, but! I read somewhere that if I use in request withCredentials: true, it will manually attach the token to headers as a Authorization Bearer. Also, question came to my head – would it be really bad if save the token in localStorage?
Here’s the Laravel part, which returns the token from log in:
$token = Auth::user()->createToken('basic-app-token')->plainTextToken;
$cookie = cookie('auth_token', $token, 30, null, null, false, true, false, 'Strict');
return $this->successfullRequest($response, $message,200)->withCookie($cookie);
Maybe there is no point of attaching my own cookie? And Laravel from /sanctum/csrf-cookie will recognise the user and authorise it?
User successfully logs in and receives token:
await axios.get('http://localhost:5000/sanctum/csrf-cookie', {
withCredentials: true
});
const {data: {data: {user, token}}} = await axios.post('http://localhost:5000/api/v1/auth/login', userData, {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true,
});
The very next request to protected route looks like this:
const request = await axios.get('http://localhost:5000/api/v1/company', {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
withCredentials: true
});
console.log(request); // Returns 401
2
Answers
Just noticed.. I thought I had the right .env file for SANCTUM_STATEFUL_DOMAINS... It was
SANCTUM_STATEFUL_DOMAINS=localhost
, had to have the port of my SPA, for the current case:SANCTUM_STATEFUL_DOMAINS=localhost:3000
On the backend side you should find the user in the database and create a token for them, then return them to the frontend.
on the front end you should store the token either in localStorage or in Cookie (this is the priority), but for the sake of simplicity, you can put it in localstorage. And then add
Bearer + token
to eachaxios
request.If you want to use Cookie then you need withCredentials, in case of localStorage you don’t need to think about it.
Sanctum Guard will take the token itself and check if it exists in the database. You can see this in
vendor/laravel/sanctum/src/Guard.php