如何使用Laravel 5.5身份验证使电子邮件登录不区分大小写



在构建应用程序时,我通过运行php artisan make:auth使用了Laravel身份验证脚手架,这很棒,为我节省了大量时间。

但是,我遇到了用户无法登录的问题,因为他们不记得最初注册时用于电子邮件的大小写。

例如,注册Myemail@domain.com的用户无法使用myemail@domain.com登录。

我从研究中了解到,从技术上讲,@ 之前的部分根据规范区分大小写,并且上面的两封电子邮件理论上可能属于两个不同的人。不过,就我而言,我认为这不足以让我需要在登录时强制执行。

我正在使用 Postgres 数据库,因此我希望将Auth::attempt()中的电子邮件数据库查找替换为ilike而不是like(如果可能的话)。但是,我一生都找不到它在源代码中的位置,因此不知道我将如何覆盖它。

Tl;博士如何覆盖 Laravel 的默认身份验证以不区分大小写的方式进行电子邮件查找?

溶液

我最终通过首先听取@btl建议并在电子邮件属性上实现突变器方法来解决问题。我不想为现有用户浏览和更改所有电子邮件,并且觉得万一我遇到想要恢复区分大小写的问题,我想要一个可以轻松撤消的解决方案。

应用/用户.php

public function getEmailAttribute($value) {
return strtolower($value);
}

app/Http/Controllers/Auth/LoginController.php

protected function credentials()
{
$username = $this->username();
$credentials = request()->only($username, 'password');
if (isset($credentials[$username])) {
$credentials[$username] = strtolower($credentials[$username]);
}
return $credentials;
}

不幸的是,我不知道如何将同样的逻辑应用于ForgotPasswordController.php但现在我会活下去。无论现在的电子邮件大小写如何,登录似乎都可以工作。

在用户模型上添加一个突变器方法,使电子邮件全部小写:

public function setEmailAttribute($value)
{
$this->attributes['email'] = strtolower($value);
}

每当用户注册时,电子邮件将始终转换为小写。

或者,在用户模型上使用访问器:

public function getEmailAttribute($value)
{
return strtolower($value);
}

这样,原始值将保留在数据库中,但每当您调用$user->email时,它将是小写的。在进行严格比较时,您只需要将登录时用户的输入转换为小写。

您也可以进行自定义尝试。

$credentials = ['email' => 'useremail@gmail.com', 'psasword' => 1234];
public function checkAttempt($credentials)
{
$user = UserTable::whereRaw('lower(email) = ? ', [$credentials['email']])->firstorFail();
$validPassword = Hash::check($credentials['password'], $user->password;
if ($user  && $validPassword)
{
// set user session over here
}
}

@btl答案是完美的,但还有另一种方法。

您可以编辑注册控制器。

App/Http/Controller/Auth/RegisterController.php

protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => strtolower($data['email']),
'password' => bcrypt($data['password']),
]);
}

我想保持大小写(在我的情况下是用户名)在数据库中指定的方式。我能找到的唯一方法是覆盖UserProvider(特别是retrieveByCredentials部分)。对于看似简单的更改来说,这很麻烦。最后,我没有使用 Auth::try 方法,而是通过手动检索用户、检查密码,然后使用 Auth::login 方法解决了这个问题:

$user = User::where('username', 'ilike', $req->input('username'))->first();
if (!$user ||
!Hash::check($req->input('password'), $user->password)
) {
return response()->json(['status' => 'FAILED']);
}
Auth::login($user);

我解决了登录控制器中的 ovveriding 凭据函数

function credentials(Request $request)
{
return ["email"=> strtolower($request->email), "password"=> request('password')];
}

最新更新