Laravel Sanctum 401 error after on reloading - laravel

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?

Related

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

419 error in second login after a logout in a SPA using Laravel API and Vue.js

I'm getting a page expired error (er.419) when I try to login after a previous logout.
I'm working on auth pages for SPA made with Laravel and Vue.js. It works well on first login but after a logout it shows an error submitting the second one login.
I think the issue is the CSRF sent previously and (maybe) expired after logout.
My work flow is this:
login component has hidden form sent as POST method to Laravel API having the csfr-token value from an HTML META TAG set up when app is created by Laravel template:
meta name="login-status" content="{{ Auth::check() }}"
The logout is done by a fetch request in a vue component. So no refresh is done.
Thanks for any suggestion!
From the laravel docs (https://laravel.com/docs/5.8/csrf#csrf-introduction):
Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application.
When you logout, you are invalidating your current session - which means that the csrf token you have cached in your meta becomes invalid.
Solution 1
Refresh the page when you successfully logout, so php can output the active csrf token into your meta tag. For example:
fetch('/api/logout', {
method: 'post'
}).then(() => {
window.location.href = '/login';
});
Solution 2
Consider using the api route middleware group. Doing so will mean the application will not trigger the App\Http\Middleware\VerifyCsrfToken middleware. Bear in mind though that you will no longer have access to the session, so you'll need to look into stateless authentication techniques such as via JWT's.
Laravel themselves even provide a package for authenticating api's. (https://laravel.com/docs/5.8/passport)

Laravel passport Oauth2 "Requesting Tokens"

I am working with Zapier, and trying to authenticate user using OAuth2. I am using the Laravel(5.5) Passport(^4.0).
I am trying to use defalut passport routes "https://laravel.com/docs/5.5/passport".
But when it goes to "oauth/authorize" GET method and if user is not logged in then gives me {"error":"Unauthenticated."} instead of redirecting to Login page. And if user is logged in already then worked well.
Is there something i am missing and where I can check to resolve this issue.
Thanks and Regards
You are working with Oauth2 so you will get 401 and {"error" : "Unauthenticated"}. It is up to you to handle the unauthenticated response to the server (e.g. your js front end will redirect or your mobile app show login page).

Passing accessToken from frontend to PHP API

I've been trying to get authentication working (described below) in my laravel application, following these two tutorials:
https://auth0.com/docs/quickstart/webapp/laravel/01-login
https://auth0.com/docs/quickstart/backend/laravel/01-authorization
On the frontend (angular app):
User clicks log in button and taken to auth0 login page
The user logs in and is redirected back to the callback with the accessToken
The access token is stored on the frontend and passed to Laravel API each request.
On the backend:
User makes a request to my http://localhost/api/route passing the accessToken in the authorisation header
Laravel validates the user is logged in and valid.
Laravel allows access to that route
It works to an extend, but when I try to use postman to access the protected route by passing the accessToken I get the error:
"message": "We can't trust on a token issued by: https://myprojectname.au.auth0.com/."
Is my workflow correct? What am I missing?
Thanks!
Just in case if somebody facing with the same issue. The authorized_iss must contain a trailing slash.
In the laravel-auth0.php file the field,
'authorized_issuers' => 'https://myprojectname.au.auth0.com/'
should be in this form.

Resources