How to use Multiple Users Authentication Guards and Login Throttling in Laravel
Laravel provides all the tools from simple to advance authentication functionality and also enough space for customization. So in this post, you’ll be learning about How to use Multiple Users Authentication Guards and Login Throttling in Laravel.
First, let’s create an app\Http\Controllers\LoginController.php.
php artisan make:controller LoginController
Authenticating Users for Login
use Illuminate\Support\Facades\Auth; if (Auth::attempt( [ 'email' => $request->email, 'password' => $request->password ] , $remember_me ) ) { // after true the users will automatically be remembered and you can access user instance using Auth::user() method. }
You can also pass custom keys in an array such as username or status etc.
Auth::attempt( [ 'username' => $request->username, 'password' => $request->password, 'status' => 'active' ] , $remember_me )
The $remember_me
takes a boolean value and is set to false
by default.
Access User Instance after login
The Auth
facade can be used to get the instance of the current logged in user for this you have to access a static method user()
.
Auth::user() // this will get you user instance object Auth::user()->id // this will get you id of the user Auth::id() // this method is short method to get id of the user
Check if a user logged in
If you just want to verify if the current user is logged in and authenticate then use Auth::check()
which returns a boolean value.
use Illuminate\Support\Facades\Auth; if (Auth::check()) { }
Manually Authenticate a User via User Instance
Let’s say that you want to login as another user but don’t have the proper login credentials then you can pass the user object into the method Auth::login( $user )
and by doing this a session is set to that user instance.
use Illuminate\Support\Facades\Auth; $user = User::find( 2 ); Auth::login( $user );
public function authenticateByInstance( Request $request ){ $user = User::find( 2 ); Auth::login( $user ); $request->session()->regenerate(); return redirect()->intended( route( 'dashboard' ) ); // intended() will redirect the user to the URL and will skip authentication middleware only once. }
Authenticate user via the id
Pass the user’s primary key to the method Auth::loginUsingId( $user_id );
and the session will be set to that particular user.
Auth::loginUsingId( $user_id );
public function authenticateById( Request $request ){ Auth::loginUsingId( 1 ); $request->session()->regenerate(); return redirect()->intended( route( 'dashboard' ) ); }
Safely Logging out Authenticated user
To safely remove the authenticated user data from the session two additional steps must be followed. First, call Auth::logout();
then flush the current session by calling $request->session()->invalidate();
and generate a fresh session token via a method $request->session()->regenerateToken();
.
Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken();
Login Form Snippet
In resources\views\login.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="{{ route( 'login.verify' ) }}" method="post"> @csrf <label for="">email</label><br> <input type="text" name="email" id="email" value="" > <br> <label for="">Password</label><br> <input type="password" name="password" id="password" value="" > <br> <label for="">Remember Me</label> <input type="checkbox" name="remember_me" id="remember_me" value="1" > <br> <input type="submit" value="Submit" > </form> </body> </html>
Login Method Snippet
In app\Http\Controllers\LoginController.php
public function verify( Request $request ){ $query = [ 'email' => $request->email, 'password' => $request->password, ]; $remember_me = ( !empty( $request->remember_me ) )? true : false; if( Auth::attempt( $query, $remember_me ) ){ $request->session()->regenerate(); return redirect()->intended( route( 'dashboard' ) ); } return back(); }
Login Throttling
Laravel login throttling enables an extra layer of security within your laravel application by limiting the rate of attempts accessing a specific URL to which data is submitted.
This feature can be used for limiting the number of incorrect login attempts from users or preventing the issue of multiple duplicate form submissions.
In this post, you’ll learn to implement throttling for application login. And for demonstration purposes, we’ll be limiting the rate of login to a single attempt per minute.
1) Start from app\Providers\RouteServiceProvider.php
and within method configureRateLimiting()
create a static method RateLimiter::for
. The method for( 'rate limiter name', callback-function )
.
2) In our case we give name as login and the second parameter will be an anonymous callback function that returns Limit
class.
Here is a code explanation.
RateLimiter::for('login', function (Request $request) { return Limit::perMinute(1); });
Here we are limiting one attempt per minute using the method perMinute(1)
. You can also use perHour()
the method to limit attempts in hours.
3) Now use login rate limiter in middleware or for a specific route you want to set.
Route::post('login/verify', [ LoginController::class, 'verify' ] )->name('login.verify')->middleware( [ 'throttle:login'] );
4) If you go back to your login page and try login in using incorrect credentials at first you will be redirected to the login page and after the second attempt an HTTP 429 – TOO MANY REQUESTS response is sent back.

laravel login throttling HTTP code 429 too many requests
You can also change and provide a custom response message by returning a response method along with Limit::perMinute(1)
.
return Limit::perMinute(1)->response(function () { return response('Try login after 1 minute', 429); });

laravel login throttling custom message for rate limiters
What are authentication Guards in Laravel?
The guards are used to logically map and retrieve the authenticate user and also specify the ways in which they must be authenticated. Further, it also allows you to change drivers that are session-based or token-based.
So let’s assume a scenario where you have two tables which are admin and another is users tables and have to authenticate users from two different tables we have to specify a guard in config\auth.php file.
Since by default the users
table is provided by laravel and now you must also want the admin
table users also be authenticated by Laravel Authentication. So for this, we’ll start by creating a new guard and name it as admin
and driver will be session
.
Create AdminModel to use for guard
This model stores and accesses data from the admin database table.
php artisan make:model AdminModel
In app\Models\AdminModel.php file.
<?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 AdminModel extends Authenticatable { use HasFactory, Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $table = "admin"; 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', ]; }
Now in the config\auth.php file add a provider admin
and specify driver and model. The supported driver is eloquent and database which specifies how data is retrieved.
The key model
takes the reflection of the AdminModel::class class. If you don’t want to specify the model then you can replace the model key with the table key and give the database table name.
Now Append below changes to your config\auth.php file.
use App\Models\AdminModel; 'guards' => [ //[...] 'admin' => [ 'driver' => 'session', 'provider' => 'admin', ], //[...] ], 'providers' => [ //[...] 'admin' => [ 'driver' => 'eloquent', 'model' => AdminModel::class, ], //[...] ],
Login using multiple authentication guards
After specifying a new guard called admin we have to mention it while authenticating a user so that laravel can access its provider and retrieve its composition. So till now, we have done all it’s required to specify a guard, and below you see how to apply them in case you have multiple of such guards.
Come to app\Http\Controllers\LoginController.php we have to refactor our LoginController verify()
method to support multiple guards.
<?php namespace App\Http\Controllers; use App\Models\AdminModel; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class LoginController extends Controller { public function verify( Request $request ){ $query = [ 'email' => $request->email, 'password' => $request->password, ]; $remember_me = ( !empty( $request->remember_me ) )? true : false; $is_authenticated = false; if( Auth::guard('web')->attempt( $query, $remember_me ) ){ Auth::shouldUse('web'); $is_authenticated = true; } if( Auth::guard('admin')->attempt( $query, $remember_me ) ){ Auth::shouldUse('admin'); $is_authenticated = true; } if( $is_authenticated ){ $request->session()->regenerate(); return redirect()->intended( route( 'dashboard' ) ); } return back(); } }
First, the login credentials are matched with the first once and it successful that session is automatically created for that users and if the user is invalid then the credentials are matched with the Auth::guard('admin')->attempt( $query, $remember_me )
now if this is true
then the session will be generated for the admin guard.
Don’t miss this?
Did you see that I have called Auth::shouldUse('web');
method after the attempt()
method on each. This is to set and tell laravel authentication that you’ll be using this particular guard throughout the application.
This is necessary to do so because Laravel Authentication by default uses web guard and if you log in via admin guard then the Auth::user()
will return null
.
Protecting Web Routes
Even though you have set Auth::shouldUse( );
it once during login verification. It is mandatory to set it on every request for that I have created a GuardAuth
Middleware will set the guard on every request or else even after successful login you will receive user instance as NULL.
In app\Http\Middleware\GuardAuth.php.
<?php namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; use Closure; use Illuminate\Support\Facades\Auth; class GuardAuth extends Middleware { public function handle($request, Closure $next, ...$guards) { $guards = config( 'auth.guards' ); foreach( $guards as $guard => $guard_arr ){ if( Auth::guard( $guard )->check() ){ Auth::shouldUse( $guard ); } } if( !Auth::check() ){ return redirect( route('login') ); } return $next($request); } }
Register the GuardAuth middleware into the app\Http\Kernal.php.
protected $routeMiddleware = [ // [...] 'guard_auth' => GuardAuth::class, // [...] ];
For authenticating users in very request use guard_auth
middleware is theirs. You can apply this to a single or to a group of routes.
In routes\web.php
Route::get('dashboard', [ DashboardController::class, 'index' ] )->name('dashboard')->middleware( ['guard_auth'] ); // single route // Multiple routes Route::group(['middleware' => [ 'guard_auth' ] ], function ($router) { Route::get('dashboard', [ DashboardController::class, 'index' ] )->name('dashboard') });
Video Tutorial
Related Posts
- PHP Laravel Restful API Authentication with JWT Token using Postman
- Laravel Livewire | Login & Dynamic Registration Form for Multiple Roles




