php - Laravel Passport no authentication
I have some strange problems with my laravel app. I have created an authentication system with Passport, I have installed everything as needed but I can't authenticate the user. When I log in it's creating a token correctly and everything seems to work fine, but when I want to add authentication in postman, it's always "Not Authenticated". This is happening with Laravel 8, I have copied everything from my Laravel 7 app and there is working pretty fine. I will provide you with some code.
This is middleware that I created to check authentication:
public function handle(Request $request, Closure $next)
{
if(!Auth::id()){
return response()->json(['response' => false, 'status' => 403, 'message' => 'Not Authenticated'], 403);
} else {
return $next($request);
}
}
Here is Kernel
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\UserSecurity::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'check.auth' => \App\Http\Middleware\UserAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
And here is application.blade.php
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico"> -->
<title>Vuexy - Vuejs, HTML & Laravel Admin Dashboard Template</title>
<!-- Styles -->
<link rel="stylesheet" href="{{ asset(mix('css/main.css')) }}">
<link rel="stylesheet" href="{{ asset(mix('css/iconfont.css')) }}">
<link rel="stylesheet" href="{{ asset(mix('css/material-icons/material-icons.css')) }}">
<link rel="stylesheet" href="{{ asset(mix('css/vuesax.css')) }}">
<link rel="stylesheet" href="{{ asset(mix('css/prism-tomorrow.css')) }}">
<link rel="stylesheet" href="{{ asset(mix('css/app.css')) }}">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
<!-- Favicon -->
<link rel="shortcut icon" href="{{ asset('images/logo/favicon.png') }}">
</head>
<body>
<noscript>
<strong>We're sorry but Vuexy - Vuejs, HTML & Laravel Admin Dashboard Template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
</div>
<!-- <script src="js/app.js"></script> -->
<script src="{{ asset(mix('js/app.js')) }}"></script>
</body>
</html>
And here is the Router:
Route::group(['middleware' => 'auth:api', 'middleware' => 'auth:api'], function() {
Route::get('profile', [UserController::class, 'getUserDetails'])->name('profile');
Route::post('logout', [UserController::class, 'destroySession'])->name('logout');
});
Now what I have noticed is, when I use auth:API and not my middleware, I'm getting error like:
RuntimeException: Session store not set on request. in file C:\xampp\htdocs\sss\vendor\laravel\framework\src\Illuminate\Http\Request.php on line 483
Any ideas?
Answer
Solution:
After I did my research I found solution but it's not suitable for me:
I changed middleware in my routes to be auth:api
and before that was check.auth
, and I removed \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class
, and now it works.
The real question is, why is my middleware not working?
Answer
Solution:
You middlware doesn't work because you are not checking the right guard.
Since you are not providing any guard in your check, Laravel will fallback to the default guard thus the web
guard (defined in your config/auth.php
).
To make your middleware work, edit the line with the following:
if(!Auth::guard('api')->check())
Cordially
Answer
Solution:
Your condition was wrong; you should write instead:
public function handle(Request $request, Closure $next) {
if(auth()->check()){
return $next($request);
}
return response()->json(['response' => false,'status' => 403,'message' => 'Not Authenticated'], 403);
}
Source