Laravel sanctum SPA authentication logout is not working - laravel

I am using laravel sanctum SPA authentication in my Vue project.Everything is working well but even after logout
Auth::logout()
I am still able to get datas from api route inside middleware
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
I should not be able to get datas after logout.It should show 401 unauthenticated but its not the case.
How to solve this problem.I have been stuck here for 3 days.I followed laravel documentation and other tutorial as well but every one logged out same like I did.

Kindly use Auth::guard('web')->logout(); instead of Auth::logout(). look into SPA Log out issue

To Logout, a user simply do this in you logout function to delete all the user tokens
public function logout(Request $request) {
auth()->user()->tokens()->delete();
}
Or user this to remove only the active token
$request->user()->currentAccessToken()->delete();

What worked for me now is :
auth('sanctum')->user()->tokens()->delete();

In order to logout the specific user, You need to specify the user.
// Revoke a specific user token
Auth::user()->tokens()->where('id', $id)->delete();
// Get user who requested the logout
$user = request()->user(); //or Auth::user()
// Revoke current user token
$user->tokens()->where('id', $user->currentAccessToken()->id)->delete()

Related

Laravel Jetstream/Sanctum API authentication

I have been working with Laravel since version 5.X up to version 8.X but always use it for backend API (never used blade template), and always pair it with VueJS on the front-end using JWT authentication (also never messed with any other authentication method).
Now with Laravel 9 and Vue 3, Im trying to use native Laravel Jetstream that uses SANCTUM and Vue+Inertia JS, and I'm quite lost with the authentication process. with JWT method, once the user succesfully login on the browser, all api request to Laravel will be authenticated using Authoraziation header. but this seems a different case with Sanctum.
After deploying and installing Jetstream and completed all the set-up. I created a user and loggedin with that user details. and I notice few things, there is a default API route
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
when I tried to directly access my.domain/api/user I notice it was redirected to GET /login
then redirected again to GET /dashboard
I then created a test api route using below
Route::get('test', function( Request $req) {
dd( [
'test' => $req->all(),
'user' => auth()->user(),
'request' => $req
] );
});
and I notice this request is not authenticated even when the cookies is present on the request as Im when I'm alraedy logged-in on the same browser, the auth()->user() is null.
I tried adding auth:sanctum middleware
Route::middleware('auth:sanctum')->get('test', function( Request $req) {
dd( [
'test' => $req->all(),
'user' => auth()->user(),
'request' => $req
] );
});
but having sanctum middle behave the same as the api/user where if i open api/test directly on the browser, it gets redirected to GET /login then redirected again to GET /dashboard and I'm quite lost at this point. I tried reading the docs and it says I have to do a separate authentication for this that would issue an API token and I was thinking I might better be going back with using JWT auth as it seems a lot easier to deal with.
So my question is; How can I authenticate an API end-point without having to redirect it to /login then /dashboard if the user is already logged in on my application using default sanctum authentication.
My goal is just to simply create /api/test that will be automatically authenticated if user already loggedin on the same browser and return the data I set on its return value and not doing any redirects.
Appreciate any help
I have got the same issue with laravel8
Jetstream and inertia vue3.
Am looking for the solution since 3 days posting messages on discord, searching on YouTube and more but nothing.
When i make an api call from your SPA to laravel, i got UNAUTHENTICATED response.
on postman you need put
headers
Accept = application/json
this tells your application know how works with Json
and go stop redirect to "Login"

Sanctum Security Access with no token,

I'm using Laravel 8 / VueJs / Sanctum. And I found a small issue I'm not sure if its a security issue or not but I'm thinking its an exploit in Sanctum
I'm calling my Vue components in my blade files
And I can send and receive the response to all routes that I have in api.php without sending the token.
Also : All my routes are in sanctum middleware as you can see
all my routes are working fine but the one /user it redirect me to home
is that possible to receive a response without sending a token, after I logged in ?
if Yes why I can receive a response from all my routes but /user it redirect me to /home
Route::middleware(['auth:sanctum'])->group(function () {
Route::get('/user', function(Request $request){
return $request->user();
});
// Chat routes
Route::prefix('/chat')->group(function(){
Route::post('/messages', [App\Http\Controllers\Api\ApiChatController::class, 'store'])->name('api/send-message');
Route::get('/messages', [App\Http\Controllers\Api\ApiChatController::class, 'show'])->name('api/recent-chat');
Route::get('/messages/{user}', [App\Http\Controllers\Api\ApiChatController::class, 'show'])->name('api/open-chat');
Route::get('/threads', [App\Http\Controllers\Api\ApiChatController::class, 'index'])->name('api/all-chat-threads');
});
// dating routes
Route::prefix('/dating')->group(function(){
Route::get('/search', [App\Http\Controllers\DatingController::class, 'search'])->name('api/search');
});
});
Sanctum using token and cookie too for user auth. If you are calling over the browser a page which is guarded by sanctum then laravel use cookie auth. if you make a api calling by javascript then laravel needs the token.
So i think everything is right.

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

register a public api route in laravel nova without authentication

I am developing a card for Laravel nova.
As part of this, I want an API route that can be posted, but I don't want to have to authenticate against it.
I have registered my route in the card's api.php
Route::post('/endpoint/{id}', function (Request $request, $id) {)
This works if I call it with an already authenticated session.
But if I try to call it from postman I get
HTTP 419 Sorry, your session has expired. Please refresh and try again.
I can see that the card service provider is registering the route as so
Route::middleware(['nova'])
->prefix('nova-vendor/NovaPusherCard')
->group(__DIR__.'/../routes/api.php');
So I guess that Nova is putting some authenticated in front of the route.
Is there a way I can register the route without adding authentication?
ok so I worked it out.
I just needed to update the middleware to api instead of nova.

Laravel, can't log a user by id and then redirect him

I'm using Laravel 5.2. I'd like to log a user by his id and then redirect him to the dashboard but it's not working.
I did this:
$result = Auth::loginUsingId($id);
var_dump($result->toArray());
and the result is fine. It returns the object user with all his data.
But after redirecting the user to the dashboard with return redirect()->route('dashboard'); it send me to login page!
I discover then that Auth::user() returns null !
What shall i do?
Thanks
Authentication needs sessions and for sessions to work you need to use the web middleware. So the routes that need working sessions should be defined like this:
Route::group(['middleware' => ['web']], function () {
// Routes that need sessions go here
});
Use $redirectTo as stated in the documentation, if you get into login again Auth wasn't successful, perhaps something related with session or cookies, or just a bad time configuration. Try Auth::loginUsingId($id, true); then.

Resources