Recently I encountered a problem at work that required multi-field verification. I finally solved it by searching for relevant information. The following article mainly introduces to you the solution to how Laravel implements user multi-field authentication. The article uses examples. The code introduction is very detailed. Friends who need it can refer to it. Let’s take a look together.
Preface
This article mainly introduces the relevant content about Laravel user multi-field authentication, and shares it for your reference and study. The following words Not much more to say, let’s take a look at the detailed introduction.
Solution:
No more than two login fields (simple solution)
The login fields are greater than or equal to three (relatively complicated)
The login fields do not exceed two
I saw a relatively simple solution online, but it cannot solve the validation of all two fields:
filter_var($request->input('login'), FILTER_VALIDATE_EMAIL) ? 'email' : 'name'
Filter the form content in the request to distinguish username. The disadvantages are obvious. If the other one is not email, you will be blinded... Here is another general solution:
Override the login method in LoginController
public function login(Requests $request) { //假设字段是 email if ($this->guard()->attempt($request->only('email', 'password'))) { return $this->sendLoginResponse($request); } //假设字段是 mobile if ($this->guard()->attempt($request->only('mobile', 'password'))) { return $this->sendLoginResponse($request); } //假设字段是 username if ($this->guard()->attempt($request->only('username', 'password'))) { return $this->sendLoginResponse($request); } return $this->sendFailedLoginResponse($request); }
It can be seen that although it can solve the problem, it is obviously contrary to the elegant style of Laravel and has cost so many troubles. Let me share my solution with you.
Login fields greater than or equal to three (relatively complicated)
First you need to implement an implementation of Illuminate\Contracts\Auth\UserProvider. For details, please refer to Adding a Custom User Provider, but I like to be lazy, so I directly inherited EloquentUserProvider and overridden the retrieveByCredentials method:
public function retrieveByCredentials(array $credentials) { if (empty($credentials)) { 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->createModel()->newQuery(); foreach ($credentials as $key => $value) { if (! Str::contains($key, 'password')) { $query->orWhere($key, $value); } } return $query->first(); }
Note: Change $query->where($key, $value);
to $query->orWhere($key, $value);
and that’s it!
Then you need to register a custom UserProvider:
class AuthServiceProvider extends ServiceProvider { /** * 注册任何应用认证/授权服务。 * * @return void */ public function boot() { $this->registerPolicies(); Auth::provider('custom', function ($app, array $config) { // 返回 Illuminate\Contracts\Auth\UserProvider 实例... return new CustomUserProvider(new BcryptHasher(), config('auth.providers.custom.model')); }); } }
Finally, we modify the configuration of auth.php and it’s done:
'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'custom' => [ 'driver' => 'custom', 'model' => App\Models\User::class, ], ],
Modify the provider of the web array to the custom registered previously
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'custom', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
Now even if you have multiple fields All right...
The above is the detailed content of Solve Laravel to implement user multi-field authentication. For more information, please follow other related articles on the PHP Chinese website!