当电子邮件地址不唯一时,laravel 中的密码重置

Tan*_*may 1 authentication laravel

这听起来像是一种反模式或薄弱的系统设计,但我的应用程序的客户端要求可以有多个用户使用相同的电子邮件地址。

所以我username在用户表中添加了另一个唯一的列,并->unique()email列中删除了约束。

注册,登录工作正常,但在密码重置期间出现问题。

考虑以下场景:

用户名 - johndoe,电子邮件 - john@example.com

用户名 - janedoe,电子邮件 - john@example.com

用户名 - jimmydoe,电子邮件 - john@example.com

如果他们中的任何一个请求密码重置链接,他们将不得不使用 johndoe@example.com 作为他们的电子邮件。那么当他们点击邮件中的重置链接时,哪个用户的密码实际上会被重置?原来,第一个用户,在本例中,是 johndoe。即使请求是由 janedoe 或 jimmydoe 提出的。

那么如何为单个用户名而不是电子邮件重置密码?我应该在 ForgotPasswordController 和/或 ResetPasswordController 控制器中进行哪些更改来解决这个问题?或者,我是否必须在核心框架中进行更改?如果是这样,在哪里以及如何?

iam*_*.in 7

在 Laravel 5.3 中测试[这个答案修改了一些核心文件(如果有能力,你可以覆盖它),这不是一个干净的解决方案。]

  1. 要求用户提供独特的username价值,而不是email密码忘记形式
  2. 重写sendResetLinkEmail()方法ForgotPasswordController.php如下。[原文写于SendsPasswordResetEmails.php]。

    public function sendResetLinkEmail(Request $request)
    {
        $this->validateEmail($request);
    
        $response = $this->broker()->sendResetLink(
            $request->only('username')
        );
    
        return $response == Password::RESET_LINK_SENT
                    ? $this->sendResetLinkResponse($response)
                    : $this->sendResetLinkFailedResponse($request, $response);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您还需要覆盖该validateEmail()方法。

    protected function validateEmail(Request $request)
    {
        $this->validate($request, ['username' => 'required']);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 添加username字段而不是email密码重置形式

  5. 覆盖rules()ResetPasswordController.php超过来的电子邮件场变化。

     protected function rules()
        {
            return [
                'token' => 'required',
                'username' => 'required',
                'password' => 'required|confirmed|min:6',
            ];
        }
    
    Run Code Online (Sandbox Code Playgroud)
  6. 也覆盖credentials()inResetPasswordController.php

    protected function credentials(Request $request)
        {
            return $request->only(
                'username', 'password', 'password_confirmation', 'token'
            );
        }
    
    Run Code Online (Sandbox Code Playgroud)
  7. 更新或覆盖以下getEmailForPasswordReset()方法Illuminate\Auth\Passwords\CanResetPassword.php

    public function getEmailForPasswordReset()
        {
            return $this->username;
        }
    
    Run Code Online (Sandbox Code Playgroud)

Laravel 使用键值对来查找用户并发送电子邮件。如果您通过'username => 'xyz',它将'xyz'username字段中查找具有值的第一条记录。

注意:users 表中的唯一列应为username. Illuminate\Auth\Passwords\CanResetPassword.php是一个特征,我无法覆盖该getEmailForPasswordReset方法,所以我只是修改了核心文件本身。