Laravel Sanctum returns 401 - laravel

I try to access my Laraval API from my Vue SPA but everytime I do a request I get a 401 Unauthorized. I have tried the answers from multiple SO questions but nothing works.
I added the EnsureFrontendRequestsAreStateful to the API middleware.
I set the Valet domain that I use for SANCTUM_STATEFUL_DOMAINS=goya.app.
I set the session envs:
SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_DOMAIN=.goya.app
In Vue I have axios.defaults.withCredentials enabled.
In the request headers I see that the XSRF token is sent.
What else can I try to fix this?

Related

Laravel Sanctum 401 error after on reloading

I am using Laravel Sanctum's API Tokens to authenticate requests from a React application. I don't use SPA Authentication and cookies.
For now, the Laravel sessions are managed with files.
After you login, you get a token, and with the given token, you can call APIs successfully. But if you refresh a page, even with the same token, API calls fail with 401 status code and the following message:
{
"message": "Given authorization token is not valid. Please try to login again."
}
It works fine on my localhost. It only happens on a live site, and after you refresh a page.
The Laravel backend serves only APIs, so it defines routes in api.php only. All these routes are using auth:sanctum middleware (of course, with an exception of /login route).
The following line is disabled in Kernel.php for the api middleware group:
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
Any thoughts on how to fix this?

AJAX request to Laravel backend returns 419 CSRF token mismatch

I'm creating a SPA using NextJS and I have a Laravel backend for my API. To authenticate my SPA I'm using laravel sanctum.
My API is on api.domain.com and my app is on domain.com
I've set these environment variables which are relevant to this issue:
SESSION_DRIVER=cookie
SESSION_DOMAIN=.domain.com
SANCTUM_STATEFUL_DOMAINS="domain.com"
When I log in I make a request to /sanctum/csrf-cookie to get my CSRF cookie, and I can see in my following requests I am sending the X-XSRF-TOKEN header with the value from the cookie.
I'm wondering if anyone else has had a similar issue with CSRF mismatches when using sanctum on different subdomains?
OK what ended up fixing my issue is changing the name of my session cookie to something without an underscore, very weird!

Laravel returns unauthorized with second request

I'm trying to create SPA. I use Laravel API for backend and Nuxt.js for frontend. I want to authenticate users via Laravel Sanctum. I run backend on localhost:8000 and frontend on localhost:3000. SANCTUM_STATEFUL_DOMAINS is set to localhost:3000, SESSION_DOMAIN is set to localhost and SESSION_DRIVER is set to cookie.
I created login and logout in my app and everything works great until I make first request after logging in. I just wanted my app to return all users:
Route::middleware('auth:sanctum')->get('/users', function() { return User::all(); });
but it returns 401 unauthenticated. I don't know why is that happening. The route used for returning logged in user uses the same middleware:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
and works perfectly (Nuxt returns logged in user with every page change). I called users route with axios:
axios.get('http://localhost:8000/api/users')
What can cause this problem? This is very frustrating because I struggled a lot just to get the login and logout working.
I also thought about running API on api.domain.test and frontend on domain.test but is it possible to hook up a domain like that to Nuxt locally?
It returns unauthorized because the call to the endpoint doesn't have access token of the user.
The idea is that when you login auth:sanctum returns access token to the client so that it can use it to access the data in all of it's next calls.
To do that you need to use authentication module in nuxt check this
The problem you are going to face next is that SPA doesn't have middleware so you need to set your app as universal instead of spa to be able to use the middleware in the client side

Laravel Sanctum CSRF Cookie Request Optional

I am trying to use Laravel Sanctum for my SPA. There are some basic home pages from web.php routes but other axios API interactions with the SPA are in api.php routes guarded by auth:sanctum
From the official documentation (https://laravel.com/docs/7.x/sanctum#spa-authenticating), it says we have to send a request to /sanctum/csrf-cookie to initialize CSRF protection prior login. However, I noticed that even without login, Laravel by default already initialized XSRF-TOKEN and <app_name>_session cookies to my browser. I do not need to initialize it via /sanctum/csrf-cookie and my subsequent API request in the logged-in SPA still works. Later I checked https://laravel.com/docs/7.x/csrf#csrf-x-xsrf-token and it says it is the default behavior that Laravel will include the CSRF token in each response.
My question is, is it true that /sanctum/csrf-cookie initialization is optional and it is safe for axios to use the default CSRF token return by Laravel? Or am I doing something wrong which exposes my SPA to CSRF attack?
Your main SPA home page is probably provided by a route that is defined in your web.php route file as you mentionned. In App/Http/Kernel.php, check in your middleware groups if there is VerifyCsrfToken::class defined as a middleware for web :
protected $middlewareGroups = [
'web' => [
...
StartSession::class,
...
VerifyCsrfToken::class,
...
]
]
This middleware is responsible for creating header response like : set-cookie XSRF-TOKEN=kgXZBZ4AccC0H17KEMw.... when you request any route available in web.php (if the cookie yet doesn't exist obviously), that will indeed initialize a XSRF-TOKEN cookie.
Therefore, you don't need to request route /sanctum/csrf-cookie when you already use this VerifyCsrfToken middleware.
However, if you are doing full SPA totally separated from your Laravel backend and deliver a html page differently, you won't have this XSRF-TOKEN cookie generated by default. Thus, as mentionned in Sanctum documentation, you need to request /sanctum/csrf-cookie to generate cookie before going further.

Deploy Laravel with Sanctum into Heroku - CSRF token mismatch

I developed a Laravel+Vue with Sanctum and deployed. On localhost works fine, I can login with my Vue form or with Laravel UI. In Heroku I get a CSRF Token mismatch error if I try to login with my Vue form; if I login with Laravel UI I get a 419 error page.
What I can note is that on my Heroku's app I haven't got any XSRF_TOKEN in my cookies, but in my localhost I have. I tried changing session driver from file to database driver as I read that in Heroku file driver doesn't work fine because of its storage system, with the same results (CSRF Token mismatch and not XSRF-TOKEN).
I also tried with http and https.
app/Http/Kernel.php in protected $middlewareGroups
// \App\Http\Middleware\VerifyCsrfToken::class,

Resources