If you have ever used Laravel's auth setup even once, you know how much time it can potentially save when we just want to get going. But, I am not going to talk about what comes with the auth scaffolding. I am here to talk about why it is ok to modify the Login and Register controller which comes by default and how we are going to customise them to our unique requirements.
So, to start with I wanted to have a Google reCAPTCHA in my registration form. I want to make sure only humans are able to fill the form, and there is some way to stop the bots/scripts from mass submitting my registration form. I would say this is a very common requirement and my initial question was - can I modify the code which comes out of the box with Auth and not rewrite the code which already serves 90% of my requirements?
Well, I found out the answer was yes. Taylor has given us a lot of control and customisation options by using traits. If we see the RegisterController, it uses a trait "RegistersUsers". A lot of logic related to registration of a user comes from this trait. And, we can customize this as much as we want to without breaking anything or touching the core framework.
So, the first thing that I wanted to ensure during registration was the validation to respect the reCAPTCHA field (by the way I have used this package: https://github.com/anhskohbo/no-captcha for implementing reCAPTCHA and if you want to see how to do that, you can watch this video on my Youtube channel) and so the first modification that I did was to modify the "validator" which is already inside the RegisterController (I am using Laravel 5.6).
So, I just added an additional field to the array of validation fields and my final validator function code looked something like this
So, this was easy right? The rest of the logic related to checking the required value and also to test whether the token is correct is already part of the package and I am not going into details about that.
The next requirement was that when a user fills up the form, we should not directly allow that user to log in. The account should be inactive and can only be activated by clicking a link which the user will get on the email id that was mentioned during the registration.
Again, this was a very simple modification - the function "create" is already part of the RegisterController and we just need to ensure that we make the user's status inactive. And I was able to do that with the below code
So, most of our work is done, right? The form now has a Captcha, the user which is getting created is inactive. The last piece was overriding the behaviour of post registration. By default, when a user registers; Laravel automatically creates a session for him and redirects him to the home page. But, we don't want that to happen. We don't want the session to start and the user should go back to the welcome page and not home page right?
So, for that we modify the register function in the trait. Yes, because this entire thing is part of the trait; the sequence is simple - functions inside the controller with the same name overrides the function inside the trait and will have access to every variable inside the trait. So, we just remove one line which tells Laravel to login in the user which is:
And so, the final register function looks something like this:
And with this done, we just modify the private variable inside RegisterController which is "protected $redirectTo = '/';" and we are done.
Now, when a user goes to the registration page he will see the reCAPTCHA field. After registration, his/her account will continue to be inactive till the user clicks on a live to activate his/her account. And, we have modified the default behaviour of Laravel to not log in a user and redirect him/her to the home page after registration is done.
Also, as an additional requirement is that our login function should check whether the user is active or not. This can be done very easily by modifying the LoginController.
The login controller uses a trait 'AuthenticatesUsers'. From this we will modify the credentials function by passing it an array of fields that it needs to validate. This is how the final code looks:
Doing this now ensures that while checking for the authentication credentials, the additional condition of user's is_active state which will be checked.