Skip to content

Instantly share code, notes, and snippets.

@kevnk
Forked from paulofreitas/AuthServiceProvider.php
Last active May 26, 2022 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevnk/cdd5f1244d3d7abcde4edd98280d8ca2 to your computer and use it in GitHub Desktop.
Save kevnk/cdd5f1244d3d7abcde4edd98280d8ca2 to your computer and use it in GitHub Desktop.
Extending the default EloquentUserProvider (Laravel 9)
<?php
return [
/* ... */
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'custom',
'model' => App\Models\User::class,
],
],
/* ... */
];
<?php
namespace App\Providers;
use App\Auth\UserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
$this->app->auth->provider('custom', function ($app, array $config) {
return new UserProvider($app['hash'], $config['model']);
});
}
}
<?php
namespace App\Providers\Auth;
use Closure;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Str;
use Illuminate\Auth\EloquentUserProvider as BaseEloquentUserProvider;
class EloquentUserProvider extends BaseEloquentUserProvider
{
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
if (
empty($credentials) ||
(count($credentials) === 1 &&
Str::contains($this->firstCredentialKey($credentials), 'password'))
) {
return;
}
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->newModelQuery();
foreach ($credentials as $key => $value) {
if (Str::contains($key, 'password')) {
continue;
}
if (is_array($value) || $value instanceof Arrayable) {
$query->whereIn($key, $value);
} elseif ($value instanceof Closure) {
$value($query);
} else {
$query->where($key, $value);
}
}
return $query->first();
}
}
@kevnk
Copy link
Author

kevnk commented May 26, 2022

I use this to encrypt user emails.

php artisan make:migration add_email_key_to_users

// ...
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->text('email')->unique(false)->change();
            $table->string('email_key')->unique()->after('email');
        });
    }
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('email')->unique()->change();
            $table->dropUnique(['email_key']);
            $table->dropColumn('email_key');
        });
    }
// ...

app/Models/User.php

    protected $casts = [
        // ...
        'email' => 'encrypted',
    ];

    public static function boot()
    {
        parent::boot();
        self::creating(function ($user) {
            if (!$user->email_key) {
                $user->email_key = substr(md5($user->email), 0, 255);
            }
        });
    }

app/Providers/Auth/EloquentUserProvider.php:40

            // ...
            if (Str::contains($key, 'password')) {
                continue;
            }

            ## BEGIN EDIT - convert email to email_key
            if (Str::contains($key, 'email')) {
                $key = 'email_key';
                $value = substr(md5($value), 0, 255);
            }
            ## END EDIT ##

            if (is_array($value) || $value instanceof Arrayable) {
            // ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment