Why do two guards in laravel affect each other? - laravel

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

Related

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 Login to Admin dashboard redirect to 404 page after enable AuthenticateSession middleware

Im working in simple blog site using laravel which has 2 parts , blog site for users and admin dashboard
It is all works good before but after uncomment below line in Http/Kernal.php
\Illuminate\Session\Middleware\AuthenticateSession::class,
failed to login and redirect to admin dashboard and it is redirect to 404 page.
I just want to use AuthenticateSession middleware because , i want to use
logoutOtherDevices function for website users
Auth::logoutOtherDevices($request->input('new-password'));
when i comment out this line \Illuminate\Session\Middleware\AuthenticateSession::class, again it is working normal .
please help me to solve this issue .
I have users table used for login users and admin table for login admin to dashboard
here is table for admin :
here is config/auth.php :
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Model\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Model\Admin::class,
]
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
]
],
];
here is admin login function :
public function login(Request $request)
{
// Validate the form data
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password,'status'=>1], $request->remember)) {
// if successful, then redirect to their intended location
return redirect()->intended(route('admin.dashboard'));
}else{
// if unsuccessful, then redirect back to the login with the form data
return redirect()->back()->withInput($request->only('email', 'remember'));
}
}

middleware not allowing me login on web guard

i Have three Users(Staff,Admin,Hr) ...using different guards for restriction.The other guards are working fine but the web guard which is the default and guard for staff(users) is not allowing me login neither is it giving any error.
Here's my Login function
public function logged(Request $request)
{
$this->validate($request,[
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('web')->attempt(['email'=>$request->email,
'password' => $request->password]))
{
return redirect()->intended(url('/home'));
}
Session::flash('message','Invalid Login details');
return redirect()->back()->withInput($request->only('email','remember'));
}
Below is my middleware
public function handle($request, Closure $next, $guard = null)
{
switch($guard){
case 'admin':
if(Auth::guard($guard)->check()){
return redirect()->route('admin.dashboard');
}
break;
case 'hr':
if(Auth::guard($guard)->check()){
return redirect()->route('hr.dashboard');
}
break;
default:
if(Auth::guard($guard)->check()){
return redirect()->route('home');
}
return $next($request);
}
**below is my config/auth.php ** as requested
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin'=> [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
'hr' => [
'driver' => 'session',
'provider' => 'hrs',
],
'hr-api' =>[
'driver' => 'token',
'provider' => 'hrs'
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admins::class,
],
'hrs' => [
'driver' => 'eloquent',
'model' => App\Hr::class,
],
'users' => [
'driver' => 'database',
'table' => 'users',
],
],
What happens if you skip the guard and let it just use the default, so for default: do the following
if (Auth::check()) {
return redirect()->route('home');
}

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