Guards are used for authentication, and Laravel provides a built-in way to define multiple guards for different types of users.
In Laravel, you can use middleware to implement guards for different types of users, such as regular users and administrators.We need to define separate models for users and admins.
Models for User and Admin
//User
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name','email','password','image'];
}
// Admin
class Admin extends Authenticatable
{
use HasFactory;
protected $fillable = ['name', 'email', 'password','image'];
}
Make sure both models extent Authenticatable class.
Define Guards in config/auth.php
Open the config/auth.php file and define your guards.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
Define Providers
Next, define the providers for each guard.
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
Middlewares
You can create middleware to protect routes based on the guards.Here we had created two middlewares for admin.
class AdminAuthenticate extends Middleware
{
//Get the path the user should be redirected to when they are not authenticated.
protected function redirectTo(Request $request): ?string
{
return $request->expectsJson() ? null : route('admin.login');
}
// Determine if the user is logged in with Admin guards.
protected function authenticate($request, array $guards)
{
if ($this->auth->guard('admin')->check()) {
return $this->auth->shouldUse('admin');
}
$this->unauthenticated($request, ['admin']);
}
}
// AdminRedirectIfAuthenticated => Handle an incoming request
class AdminRedirectIfAuthenticated
{
public function handle(Request $request, Closure $next, string ...$guards): Response
{
if (Auth::guard('admin')->check()) {
return redirect()->route('home');
}
return $next($request);
}
}
You can also modify RedirectIfAuthenticated middleware if you want to specify the gaurd.
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
// $guards = empty($guards) ? [null] : $guards;
// foreach ($guards as $guard) {
// if (Auth::guard($guard)->check()) {
// return redirect(RouteServiceProvider::HOME);
// }
// }
if (Auth::guard('web')->check()) {
return redirect()->route('dashboard');
}
return $next($request);
}
}
Now we need to register the middlewares.Goto to your app/http/kernel.php.
'admin.auth' => \App\Http\Middleware\AdminAuthenticate::class,
'admin.guest' => \App\Http\Middleware\AdminRedirectIfAuthenticated::class,
Apply Middleware
Apply the middleware to your routes in web.php.
Route::middleware('admin.guest')->prefix('admin')->group(function () {
Route::get('/login', [AdminAuthController::class, 'login'])->name('admin.login');
Route::post('/login', [AdminAuthController::class, 'authenticate'])->name('admin.authenticate');
});
Route::middleware('admin.auth')->prefix('admin')->group(function () {
Route::get('/home', [HomeController::class, 'index'])->name('home');
});
Authentication:
When authenticating users or admins, specify the guard.
if (Auth::guard('admin')->attempt($credentials)) {
$request->session()->regenerate();
return redirect()->route('home');
}
public function logout(Request $request): RedirectResponse
{
auth()->guard('admin')->logout();
$request->session()->invalidate();
return redirect()->route('admin.login');
}
By following these steps, you can establish separate authentication systems for regular users and administrators in your Laravel application.