Laravel Multiple Guards Authentication: Middleware, Login Throttle, and Password Reset
In the previous tutorial, we talked about guards and create an admin guard with complete login functionality. Now we will learn about middleware and customize the Authenticate and RedirectIfAuthenticated middleware for our admin guard. We will also use login throttling and lastly password reset.
Whenever you want to use middleware like auth and guest for admin guard then you can use a colon between them e.g “auth:guard”. Now Open your LoginController and add:
This will specifically look for the admin guard and nothing else so guest means that the admin is not logged in and it doesn’t care if a user from web guard is logged in or not. You can also use it inside a route e.g:
Admin HomeController will have auth:admin middleware while ForgotPasswordController and ResetPasswordController will have “guest:admin” middleware. Middleware part doesn’t end here, we also want to modify the Authenticate and RedirectIfAuthenticate middleware from app/Http/Middleware directory so we get redirected to appropriate routes from different guards. Let’s open the Authenticate middleware first and modify the redirectTo() method:
Inside the redirectTo() method, we are checking inside the expectJson() that if a route name contains “admin.*” and “*” means anything that’s after “admin.” will redirect to the admin login else it will redirect us to the user login. For RedirectIfAuthenticated, we will check for the guard inside the handle method and if the guard is “admin” then we will be redirected to the admin dashboard and if not then we will be redirected to the user dashboard:
Laravel also supports login throttling which means that it will count the login attempts from a user and if that user exceeds a certain limit then it will lockout the login for a limited time. We can easily implement login throttling by using a laravel trait (it’s also being used by the default LoginController) called ThrottlesLogins. First we will import the trait and override the username() which will be used for the username() inside the ThrottlesLogins trait.
We will be using four methods from this trait and you can access a trait’s method with $this:
- hasTooManyLoginAttempts() will check if the user exceeds the max login attempts.
- fireLockoutEvent() will fire the lockout event and disable login for that user (using IP address to identify a user).
- sendLockoutResponse() will redirect back with the lockout response/message.
- incrementLoginAttempts() will track the login attempts.
Let’s add these methods to the login() method of our Admin LoginController:
We will first check if the admin has too many login attempts and if it exceeds the limit then we will fire off the event and send the admin back to the login page with lockout message. After that we are attempting to login the admin, if the login fails then we will increment the number of login attempts and call the loginFailed() method which will redirect the admin back to the login page with input.
By default, login attempts have a limit of 5 and 1 minute for blocking the admin from attempting to login again but if you want to customize this then you can define two properties $maxAttempts and $decayMinutes in your Admin LoginController (you can also define them in your default user LoginController if you want):
Unlike login, we won’t need to manually work on password reset functionality because all we need to do is send the reset email notification to a specific email. First we will work on the Admin ForgotPasswordController which will be used for displaying the reset email form and sending reset notification to that email. We are going to use SendsPasswordResetEmails trait which is also used by default ForgotPasswordController. We need three methods inside this controller showLinkRequestForm(), broker(), and guard(). showLinkRequestForm() will return a view with a form where we will enter the email for password reset. We are also defining the title and route for the view dynamically just like the login view. Since we have a custom guard so we are defining it with the guard() method and broker() will retrieve the password reset settings that we had defined in the auth.php config file. Here how our ForgotPasswordController looks like:
Also add the $title and $forgotPasswordRoute in the email.blade.php inside the auth/passwords directory:
Since we have added variables instead of text, we also need to add the showLinkRequestForm() inside the ForgotPasswordController from Controller/Auth directory:
ResetPasswordController controller will use ResetsPasswords trait which will be used for resetting the password for a certain user. Just like the above controller we will define a guard() and broker() method. We will also define the showResetForm() method which will return a view with a form for resetting the password and it has that reset token from the email as the second parameter:
We also need to define the showResetForm() in the default ResetPasswordController inside the Controllers/Auth directory:
Now we will modify the reset view from auth/passwords directory:
For email testing, we will use mailtrap which works like a sandbox and instead of sending the emails to specified users, it will capture all the emails in the mailtrap inbox. First signup with mailtrap if you haven’t already and login then click “Demo Inboxes” and you will see the credentials.
Put your “username”, “password” and set MAIL_ENCRYPTION to “tls” and restart the development server:
Your can test the reset password by going to the admin login page and clicking on the forgot password link.
Thanks for reading the tutorial and here’s the source code: