Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

sfilzek's avatar

Authenticating user against fields from a separate table

I have a situation where my application has a users and accounts table, with each account having many users.

On login I need to perform the usual user authentication, but I also need to check if the users account is enabled, and I’m unsure how to do that without overwriting large chunks of the AuthenticateUsers trait in the LoginController.

I know that I can write a custom credentials method in the LoginController to include additional fields from the users table, but how do I get that to reference a field in another table? Eg: $user->account->enabled.

Also, I need to return a different error message if the account is not enabled.

Right now I’m doing all of this with a custom login method in the LoginController, but that seems nasty.

Any pointers on how to improve this would be appreciated!

(edit: for clarification, I'm trying to change as little of the Laravel boilerplate authentication code as possible)

Cheers, Sab.

0 likes
3 replies
frankincredible's avatar

Could you add something like this on your User model?

public function login()
{
    throw_unless($this->is_enabled, new AuthenticationException('This dude is not enabled!'));

    return auth()->login($this);
}
sfilzek's avatar

Heya,

I don't understand how this method on the User model would be called from the LoginController? My current solution is similar, but it requires me to write my own login method in the LoginController, and I would prefer to keep the Laravel login code unchanged and just add hooks where I need to.

Cheers, Sab

sfilzek's avatar

Solved it:

Looking at the source for \Illuminate\Auth\SessionGuard.php it throws an undocumented (as of 7.3) event called Validated. Importantly, this event is fired after the login/password is validated, but before the user is logged in.

Adding a listener for the Validated event allows me to perform any number of additional checks, such as: is the users account active, etc. From there we can throw a ValidationException if the validation failed.

Create a new listener: Listeners/UserLoginValidated.php

<?php

namespace App\Listeners;

use Illuminate\Auth\Events\Validated;
use Illuminate\Validation\ValidationException;

class UserLoginValidated
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  Validated  $event
     * @return void
     */
    public function handle(Validated $event)
    {
        if (! $event->user->account->enabled) {
            throw ValidationException::withMessages([
                'account' => ['Account not enabled!'],
            ]);
        }
    }
}

Register the listener in EventServiceProvider.php

protected $listen = [
       ...

        'Illuminate\Auth\Events\Validated' => [
            'App\Listeners\UserLoginValidated',
        ],
    ];

Works great! :)

Please or to participate in this conversation.