Call to a member function tokens() on null on Laravel Sanctum - laravel

I get this error when i am trying to logout the user
public function logout(Request $request)
{
$request->user()->tokens()->delete();
}

You need to include the API route inner the Sanctum Auth middleware like below:
Route::group(['middleware' => ['auth:sanctum']], function() {
Route::post('logout', [AuthController::class, 'logout']);
});
Auth::user()->token() is only valid by passing the Sanctum middleware.
Check this #1
Check this #2

This worked for me, Change this code in your Controller.php to,
public function logout(Request $request){
Auth::user()->tokens()->delete();
return [
'message' => 'logged out'
];
}
And make sure your Route POST request is protected in api.php, change the code to below
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');

use token() instead of tokens()
$request->user()->token()->delete();
Or you can use it as below.
Auth::user()->tokens->each(function($token, $key) {
$token->delete();
});
by using revoke
$user = $request->user();
foreach ($user->tokens as $token) {
$token->revoke();
}

Related

Laravel Tymon jwt-auth returns 401 (Unauthorized)

When making a get-request to my Laravel backend it returns a 401 (Unauthorized). The weird thing is that a page reload fixes the issue and I get proper data back.
This is what the function I call looks like:
public function getMyCompanies()
{
$user = Auth::user();
$arrayOfCompanies = array();
foreach($user->companies as $company)
{
array_push($arrayOfCompanies, $company);
}
return response()->json([
'status' => 200,
'companies' => $arrayOfCompanies
]);
}
This is what my routes look like:
//Routes the user can always access
//Login & register
Route::post('user/register', [RegisterController::class, 'register']);
Route::post('user/login', [LoginController::class, 'login']);
Route::post('user/registerbrandwacht', [RegisterController::class, 'registerBrandwacht']);
//Password reset
Route::post('forgotPassword', [NewPasswordController::class, 'forgotPassword']);
Route::post('resetPassword', [NewPasswordController::class, 'resetPassword']);
//Routes the user should be login for
Route::middleware('jwt.auth')->group(function () {
//Everyone
Route::get('me', [UserController::class, 'me']);
Route::post('changeAccountDetails', [UserController::class, 'changeAccountDetails']);
Route::post('changePassword', [UserController::class, 'changePassword']);
Route::post('user/logout', [LoginController::class, 'logout']);
//Company
Route::post('create-company', [CompanyController::class, 'create']);
Route::get('get-my-companies', [CompanyController::class, 'getMyCompanies']);
Route::post('registerEmployee', [CompanyController::class, 'RegisterEmployee']);
Route::post('getEmployees', [CompanyController::class, 'getEmployees']);
Route::post('deleteEmployee', [CompanyController::class, 'deleteEmployee']);
});
As stated in the title I am using Tymon jwt-auth.

How to access data of rate limiters defined in RouteServiceProvider from inside any controller?

In my app/Providers/RouteServiceProvider.php I defined a rate limiter:
protected function configureRateLimiting()
{
RateLimiter::for('auth', function (Request $request) {
return Limit::perMinute(10)->by($request->ip());
});
}
I added this as middleware to my route. Now, in my custom controller I would like to read the remaining attempts. How do I get this info? I tried using RateLimiter::limiter but that returns the callback defined in the for method.
web.php routes:
Route::group(['as' => 'auth.',], function () {
Route::get('login', [AuthController::class, 'index'])->name('login');
Route::post('authenticate', [AuthController::class, 'authenticate'])->name('authenticate')->middleware(['throttle:auth']);
});
Function in my AuthController:
public function authenticate(Request $request)
{
dd( RateLimiter::limiter('auth')->remaining() ); // callback error
dd( RateLimiter::remaining('auth') ); // error because I'd have to hardcode the max attempts here
}

How to logout from any function outside a controller action in Laravel 5.5

I have been trying to log out using :
Route::get('/myland',function(){
Auth::logout();
Session::flush();
});
But the user is not being logged out. In my scenario I am obliged to logout that way without using controller I don't know what I am missing.
In AuthController/loginController constructor add below code
public function __construct()
{
$this->middleware('guest', ['except' => ['logout', 'getLogout']]);
}
or
Route::get('/myland', function(){
Auth::logout();
return redirect('/');
});

Laravel (5.4) passport routes with current user that also works if not logged in

I'm trying to make one route in laravel which can have a user if it is logged-in but can still work if not.
In my case I have a table called "venues" and a "user" that can have a venue as his favourite.
So these are my routes:
Route::group(['middleware' => ['cors', 'bindings', 'auth:api']], function () {
Route::match(['GET', 'OPTIONS'], 'venue/{venue}', 'VenuesController#getVenue')->name('venue')->where('venue', '[0-9]+');
});
Route::group(['middleware' => ['cors', 'bindings', 'api'], 'namespace' => 'Api'], function () {
Route::match(['GET', 'OPTIONS'], 'venue/{venue}', 'VenuesController#getVenue')->name('venue')->where('venue', '[0-9]+');
});
Now I noticed that Auth::user(); is only available in the route with the middleware with 'auth:api' but I also want it to get the venue if the user is not logged in. And using both groups doesn't work this way.
My Venue model looks like this:
class Venue extends Model
{
protected $appends = [
'favourite',
];
public function users()
{
return $this->belongsToMany('App\Models\User', 'venue_user');
}
public function getFavouriteAttribute()
{
$user = Auth::user();
$isFav = false;
if ($user) {
if ($user->venues) {
foreach ($user->venues as $item) {
if ($item->id === $this->id) {
$isFav = true;
}
}
}
}
return $isFav;
}
}
There must be a better way to do this.
I hope someone can help me out.
Ok I finally found the answer to my own question.
Apparently the right way to get the current of Passport is by doing:
$user = auth()->guard('api')->user();
Auth::user() is only available in routes with a middlewhere of 'auth:api' but this one is available everywhere if I say so correctly.
Feel free to correct me if I'm wrong :)

Accessing The Request Via Route Closures

In this route below, what is the user() function?
Route::group(['middleware' => 'auth:api'], function () {
Route::get('user', function (Request $request) {
return $request->user();
});
});
It's an instance of the authenticated user. It's the same as auth()->user()
https://laravel.com/docs/5.4/authentication#retrieving-the-authenticated-user
A global helper returning the user making the request. Identified through auth:api

Resources