How to add a custom User Provider in Laravel 5.4

None of the solutions I found quite worked for me, so I figured out a super easy way. (Laravel 5.4)

My problem was that I had to allow users to log in with their phone number too.

I override the EloquentUserProvider:

class PhoneUserProvider extends EloquentUserProvider
{
    public function retrieveByCredentials(array $credentials)
    {
        if (!$credentials) {
            return null;
        }

        // Fallback to original email authorization
        if (filter_var($credentials['email'], FILTER_VALIDATE_EMAIL)) {
            return parent::retrieveByCredentials($credentials);
        }

        // Assume we are logging in with a phone number
        return UserModel::where('phone', $credentials['email'])->first();
    }
}

And in my AppServiceProvider boot methode I added these lines:

Auth::setProvider(new PhoneUserProvider(app(Hasher::class), UserModel::class));

You can even set provider in login controller, based on some conditions, etc.


The solution was simple.

First, despite what other tutorials said, you do not have to register the CustomUserProvider in your config providers (Laravel 5.4 here). This was the cause of the errors I was getting.

I only had to override two methods from EloquentUserProvider, retrieveByCredentials(array $credentials) where you return a model based on the credentials provided, and validateCredentials(UserContract $user, array $credentials) where you return a boolean depending on whether credentials are correct.

You can use this same custom provider class with many providers, not just one, e.g.

'providers' => [
    'customusers' => [
        'driver' => 'jsonresponse',
        'model' => App\User::class,
    ],

    'customadmins' => [
        'driver' => 'jsonresponse',
        'model' => App\Admin::class,
    ],
],

After that, when you need to check auth with any provider, you need to provide the provider as guard e.g. Auth::guard('customusers').


Very small customizations of the EloquentUserProvider can be done by means of the following code inside the boot method of your AuthServiceProvider.

Auth::provider('eloquent', function($app, array $config)
{
  return new class($app['hash'], $config['model']) extends \Illuminate\Auth\EloquentUserProvider
  {

  };
});