laravel修改用户模块的密码验证

手动更改laravel8 自带的用户密码验证

目的是想让用户可以同时输入emial 或者 name 来进行登录

操作如下:

手动创建 EloquentUserProvider
代码如下:

class EloquentUserProvider extends BaseUserProvider{
/**
 * 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();

    // 用于标识是否是第一个登录字段,如果包含多个登录字段,使用 OR 查询
    $flag = false;
    $supportFields = config('auth.username');

    foreach ($supportFields as $field) {
        if (empty($credentials[$field])) {
            $credentials[$field] = $credentials[config('fortify.username')];
        }
    }
    foreach ($credentials as $key => $value) {
        if (Str::contains($key, 'password')) {
            continue;
        }

        if (is_array($value) || $value instanceof Arrayable) {
            $query->whereIn($key, $value);
        } else {
            if ($flag) {
                $query->orWhere($key, $value);
            } else {
                $query->where($key, $value);
                $flag = true;
            }
        }
    }
    return $query->first();
}}

修改 app/Providers/AuthServiceProvider.php

public function boot()
{
    $this->registerPolicies();
    // 通过自定义的 EloquentUserProvider 覆盖系统默认的
    Auth::provider('eloquent', function ($app, $config) {
        return new EloquentUserProvider($app->make('hash'), $config['model']);
    });
}

以上操作也是借鉴百度

更改完成后的效果
image

email可以正常登录 但是使用name登录时就提示错误

请大家帮忙检查一下代码是否存在问题,以及提出更好的修改方式。
谢谢

阅读 2.1k
1 个回答

可以尝试一下这种做法:
这是原有的username方法:

/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
    return 'email';
}

修改成如下:

/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
     $login = request()->input('identity');

     $field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
     request()->merge([$field => $login]);

     return $field;
}

并将其放入自己的loginController.php文件中
同时在login controller class中加入如下验证逻辑

/**
     * Validate the user login request.
     *
     * @param  IlluminateHttpRequest  $request
     * @return void
     *
     * @throws IlluminateValidationValidationException
     */
    protected function validateLogin(Request $request)
    {
        $messages = [
            'identity.required' => 'Email or username cannot be empty',
            'email.exists' => 'Email or username already registered',
            'username.exists' => 'Username is already registered',
            'password.required' => 'Password cannot be empty',
        ];

        $request->validate([
            'identity' => 'required|string',
            'password' => 'required|string',
            'email' => 'string|exists:users',
            'username' => 'string|exists:users',
        ], $messages);
    }

参考文章

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进