ypeError: Tymon\JWTAuth\Blacklist::__construct(): Argument #1 ($storage) must be of type Tymon\JWTAuth\Contracts\Providers\Storage, - laravel

I have followed everysteps of jwt authentication for laravel 9, However the login method not working it's alwasy saying ypeError: Tymon\JWTAuth\Blacklist::__construct(): Argument #1 ($storage) must be of type Tymon\JWTAuth\Contracts\Providers\Storage, PHPOpenSourceSaver\JWTAuth\Providers\Storage\Illuminate given, this error. I have installed composer require tymon/jwt-auth,
In kernel.php I have included 'auth.jwt'=>\App\Http\Middleware\JwtMiddleWare::class, in middlewareAliases,
This is my jwtmiddleware
<?php
namespace App\Http\Middleware;
use Closure;
use JWTAuth;
use Exception;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class JwtMiddleware extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = JWTAuth::parseToken()->authenticate();
return $next($request);
}
}
My admin login method in Admin controller
public function adminLogin(Request $request){
$credentials = $request->only('username', 'password');
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'error' => 'Invalid Credentials'
], 401);
}
} catch (JWTException $e) {
return response()->json([
'error' => 'Could not create token'
], 500);
}
return response()->json([
'token' => $token
], 200);
}
In auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'jwt',
'provider' => 'admins',
],
'manager' => [
'driver' => 'jwt',
'provider' => 'managers',
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'managers' => [
'driver' => 'eloquent',
'model' => App\Models\Manager::class,
],
'clients' => [
'driver' => 'eloquent',
'model' => App\Models\Client::class,
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'managers' => [
'driver' => 'eloquent',
'model' => App\Models\Manager::class,
],
'clients' => [
'driver' => 'eloquent',
'model' => App\Models\Client::class,
],
In api.php
Route::post('/admin/register', [
AdminController::class, 'adminRegister'
]);
Route::post('/admin/login', [
AdminController::class, 'adminLogin'
]);
Route::get('/user', [
AdminController::class, 'getUser'
])->middleware('auth.jwt');
Whats the issue and how I can solve it, I have watched other problem solving about this and none worked for me.

Related

Why do two guards in laravel affect each other?

For my e-commerce app I use the default guard for user and made another one for the control panel admin but logging in or logging out a user affects the status in admin control panel as well and the opposite is true. Why is this?
Here is my auth file:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
Here is my admin login and logout controller:
public function enter(AdminLogin $admin){
$credentials = $admin->only(['email', 'password']);
if(Auth::guard('admin')->attempt($credentials)):
$admin = ModelsAdmin::whereEmail($admin->email)->first();
Auth::login($admin);
return redirect()->route('dashboard.show');
endif;
return redirect()->back()->withMsg("There is A worng in your Credentials");
}
public function logout(){
auth('admin')->logout();
return redirect()->route('admin.login');
}
And here is my user login and logout:
public function enter(UserCheck $user){
$credentials = $user->only(['email', 'password']);
if(Auth::guard('user')->attempt($credentials)):
$login = ModelsUser::whereEmail($user->email)->first();
Auth::login($login);
return redirect()->route('user.dashboard');
endif;
return back()->withMsg('Sorry sir you Entered invalid Credentials');
}
public function logout(Request $request){
Auth::guard('user')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('user.login');
}
the problem was in the admin middleware . i made check for admin by auth()->check() it should be auth('admin')->check() because there are another middleware for user is default so the two confilicted

Laravel Sanctum can be use Multiauth guard

I'm testing with laravel sanctum but here some issues..
I'm creating Admin guard.
When I change the middleware to auth:sanctum_admin.. it should be only can access by admin but here I can access with normal user account with web guard. I don't know why?...I used passport with multiauth package.it's fine. but here in sanctum can't be separate User Table and Admin.
You can, also use multiple guards in sanctum. To achieve this, follow these steps -
Create your own guard as required. (In config/auth.php)
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
]
],
Set providers. (In config/auth.php)
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
Use this guard when you authenticate a user. (In route file)
if(auth()->guard('admin')->attempt($request->only('email','password')))
{
return auth()->guard('admin')->user();
}
#Abhishek Mitra
and for authorizatioin using Laravel Sanctum in case of Multiple Auth Guard, we can use middleware as such
Route::middleware(['auth:guard_name'])->get('/user', function(){
return auth()->guard('guard_name')->user();
}
config/auth.php
driver is sanctum
'guards' => [
'users' => [
'driver' => 'sanctum',
'provider' => 'users',
],
'partners' => [
'driver' => 'sanctum',
'provider' => 'partners',
],
'admins' => [
'driver' => 'sanctum',
'provider' => 'admins',
],
],
provider:
providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'partners' => [
'driver' => 'eloquent',
'model' => App\Models\Partner::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
model:
must be add Authenticatable
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Middleware:
Route::middleware(['auth:admin'])->get('/user', function(){
}
Guard:
auth()->guard('admin')->user();
Unauthenticated user message:
In app/Exceptions/Handler.php
use Illuminate\Auth\AuthenticationException;
function:
protected function unauthenticated($request, AuthenticationException $exception)
{
return response()->json(['message' => 'Unauthenticated.'], 401);
}
or
custom guard and custom redirect
public function render($request, Exception $exception)
{
$class = get_class($exception);
switch($class) {
case 'Illuminate\Auth\AuthenticationException':
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'login';
break;
}
return redirect()->route($login);
}
return parent::render($request, $exception);
}
you must add your custom guard in config/auth.php.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'custom-guard' => [
'driver' => 'session',
'provider' => 'custom-provider',
]
],
be careful, the driver in custom guard must be session.
and set provider as:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'custom-provider' => [
'driver' => 'eloquent',
'model' => App\CustomProvider::class,
],
],
the App\CustomProvider::class must be the model.
after that can easily use the guard in auth.
auth('custom-guard')->user()
I also face the same issue and solved it by following -
In auth.php add an extra Guard - front
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'front' => [
'driver' => 'session',
'provider' => 'members',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => Vanguard\User::class,
],
'members' => [
'driver' => 'eloquent',
'model' => Vanguard\Member::class,
],
],
Log in as a Default User or Member
/** Default Guard**/
if (Auth::attempt(['username' => $credentials['username'], 'password' => $credentials['password']], $request->get('remember'))) {
}
/** Front Guard **/
if (Auth::guard('front')->attempt(['username' => $credentials['username'], 'password' => $credentials['password']], $request->get('remember'))) {
}
Finally add the Guard in sanctum.php
'guard' => ['front','web']
In config/auth.php:
'guards' => [
...
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
],
],
(Tested in Laravel 9.x)
Defining API sanctum guards using the sanctum driver
'guards' => [
// Web Guards
'web' => [
'driver' => 'session',
'provider' => 'users',
],
//API Sanctum Guards
'admin-api' => [
'driver' => 'sanctum',
'provider' => 'admins',
],
'vendor-api' => [
'driver' => 'sanctum',
'provider' => 'vendors',
],
],
Defining Providers
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'vendors' => [
'driver' => 'eloquent',
'model' => App\Models\Vendor::class,
],
],
Generating Token
$user = Admin::where('email', $request->email)->first();
$token = $user->createToken(uniqid());
return ['token' => $token->plainTextToken];
$user = Vendor::where('email', $request->email)->first();
$token = $user->createToken(uniqid());
return ['token' => $token->plainTextToken];
Protecting Routes using sanctum guard
Route::middleware('auth:admin-api')->get('/admin', function (Request $request) {
return $request->user();
});
Route::middleware('auth:vendor-api')->get('/vendor', function (Request $request) {
return $request->user();
});
I think the default guard should be like this:
'defaults'{
'guard' : "sanctum_admin",
'passwords': 'admins',
}
Or
'defaults'{
'guard' : 'web',
'passwords' : 'users',
}

Laravel Auth::user() return null after login using guard('admin')

I have set the guard as admin like return Auth::guard('admin'). it can get data from the table 'admins' but after attempt Auth::user() return null
LoginController
===============
public function backendLogin(Request $request)
{
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
protected function guard()
{
return Auth::guard('admin');
}
config/auth.php
===============
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
I have tried many type of
auth()->guard('admin')->attempt($credentials);
Auth::guard('admin')->attempt($credentials);
but still cannot login.
For getting logged in you should use
auth('admin')->attempt($credentials))
After login you can get authenticated user's info like this for admin guard
Auth::guard('admin')->user()

Laravel: Argument 2 passed to Illuminate\Auth\SessionGuard::__construct()

I have a application where I have created a new guard called residents which is the exact copy of the default User class that comes with the laravel. But when i change the guard it start showing this error:
Argument 2 passed to Illuminate\Auth\SessionGuard::__construct() must be an instance of Illuminate\Contracts\Auth\UserProvider, null given, called in ...\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php on line 125
I tried googling for the solution and read many but nothing worked.
Laravel version is 5.8
auth.php
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'residents',
'hash' => false,
],
],
'providers' => [
'residents' => [
'driver' => 'eloquent',
'model' => App\ApiModels\Resident::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
App\ApiModels\Resident.php
namespace App\ApiModels;
use \Illuminate\Notifications\Notifiable;
use \Illuminate\Contracts\Auth\MustVerifyEmail;
use \Illuminate\Foundation\Auth\User as Authenticatable;
class Resident extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Authenticate the user
*
* #param object $request
* #return array
*/
public function _login($request)
{
if(\Auth::attempt([
'email' => $request->email,
'password' => $request->password
]))
{
return [
'success' => true
];
}
else
{
return [
'success' => false
];
}
}
}
route\api.php
Route::get('/login', 'Api\ResidentsController#login');
Api\ResidentsController.php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
/**
* Models
*/
use App\ApiModels\Resident;
class ResidentsController extends Controller
{
public function __construct()
{
/**
* Middleware(s)
*/
$this->middleware('auth:api', [
'except' => [
'login',
'logout'
]
]);
}
public function login(Request $request)
{
...
return response()->json([
'login_id' => $request->login_id,
'password' => $request->password
]);
}
}
The problem occurs in your config/auth.php. Your web guard is using the users provider which is not declared in your providers array. You have 2 options to fix this (choose one):
Add a users provider
If you're planning NOT to use the web guard, remove it instead then make your default guard to api:
'defaults' => [
'guard' => 'api',
'passwords' => 'residents',
],
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'residents',
'hash' => false,
],
],
'providers' => [
'residents' => [
'driver' => 'eloquent',
'model' => App\ApiModels\Resident::class,
],
],
'passwords' => [
'residents' => [
'provider' => 'residents',
'table' => 'password_resets',
'expire' => 60,
],
],
You Must use this for web guard:
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
Or
you can remove web guard:

laravel call to undefined method Auth guard

i want to prevent the login after register in Laravel 5.5, I already did this by commenting a line:
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
// $this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
i override it in RegisterController.php
i got this error:
Call to undefined method Illuminate\Auth\AuthenticationException::guard()
$guard = array_get($exception->guard(),0);
switch ($guard) {
case 'admin':
return redirect()->guest(route('admin.login'));
break;
default:
return redirect()->guest(route('login'));
break;
}
Here is the content of my config/auth:
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
],
],
];
i have enabled multi-auth system which is i have an admin login and a user login, what i wan't is to disable the login after register in my user page.
To check guard in the exception can do something like this:
return redirect(route(auth()->guard('admin')->check() ? 'admin.login' : 'login'));
Also, use auth() helper or Auth:: facade in the RegisterController#register if you're trying to override the method:
auth()->guard('admin')->login($user);

Resources