The following Guide is optimized for Laravel 7, but it works for Laravel 6.x and Laravel 5.x, too. Differences should only be present in the paths.

A great way to start a simple web project with PHP which needs a login and / or registration form with permissions is by using the widespread Laravel Framework with the Laratrust Package. This yields to a quick set up working system with basic functionalities.

TL;DR

Check out the short version of my StackOverflow answer.

Customize Login Validation

If the project grows, there might be a time where you want to customize the authentication mechanism by defining your own login validation: Perhaps you want to create a new status field for users to forbid the login for specific values or you want to add a lifetime (date field) for accounts that will lead to a failed login when the date-value is in the past. Anyway, you have to extend the existing login validation process.

This validation process is made in the validateCredentials method in the EloquentUserProvider class, located at [PROJECTROOT]/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php which looks as follows in Laravel 7:

/**
* Validate a user against the given credentials.
*
* @param  \Illuminate\Contracts\Auth\Authenticatable  $user
* @param  array  $credentials
* @return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
	$plain = $credentials['password'];

	return $this->hasher->check($plain, $user->getAuthPassword());
}

Default validateCredentials method in EloquentUserProvider

This method must be extended to get things working. As a good and attentive developer, you know that the framework default methods should never be touched to be more stable for future updates and avoid side effects. As a result and a possible solution, a Custom Provider can be defined to override the existing function.

Define Custom Provider and override validateCredentials

First, create a new file called CustomUserProvider.php (or a better name, for example AuthValidateStatusServiceProvider.php if you want to check the user status before login) in the app/Providers directory with the following code:

<?php

namespace App\Providers;

use Illuminate\Auth\EloquentUserProvider as UserProvider;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;


class CustomUserProvider extends UserProvider {

    /**
     * Overrides the framework defaults validate credentials method 
     *
     * @param UserContract $user
     * @param array $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials) {
        $plain = $credentials['password'];

        // PUT YOUR CUSTOM VALIDATION HERE

        return $this->hasher->check($plain, $user->getAuthPassword());
    }

}

Custom Provider

Add your custom validation and save it, for example if ($user->status != 'active') return false; if you created a status attribute for the user.

After this, Laravel must call this provider at the correct execution step. Do this by extending the boot() method in the app/Providers/AuthServiceProvider.php file to register it:

/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
	$this->registerPolicies();

	\Illuminate\Support\Facades\Auth::provider('customuserprovider', function($app, array $config) {
		return new CustomUserProvider($app['hash'], $config['model']);
	});
}

boot() method in the AuthServiceProvider

Remember to change the provider class name on both points. Furthermore, the code can be shortened with a simple import statement.

We are not done yet! The last step will be in the config/auth.php file. Scroll to the User Providers part and change it to:

'providers' => [
    'users' => [
        'driver' => 'customuserprovider',
        'model' => App\User::class,
        'table' => 'users',
    ],
],

User Providers part in auth.php

Here again: Don't forget to change the driver name (provider class name)

That's it! Now, your custom login validation should automatically be called after the user hits the Login button.