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

时间:2018-03-31 16:52:39

标签: laravel authentication

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

因此,我向users表添加了另一个名为username的唯一列,并从->unique()列中删除了email约束。

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

考虑一下情景:

  

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

     

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

     

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

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

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

3 个答案:

答案 0 :(得分:3)

在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);
    }
    
  3. 您还需要覆盖validateEmail()方法。

    protected function validateEmail(Request $request)
    {
        $this->validate($request, ['username' => 'required']);
    }
    
  4. 密码重置表单上添加username字段而非email

  5. 覆盖rules()中的ResetPasswordController.php,以便更改电子邮件字段。

     protected function rules()
        {
            return [
                'token' => 'required',
                'username' => 'required',
                'password' => 'required|confirmed|min:6',
            ];
        }
    
  6. 同时覆盖credentials()

    中的ResetPasswordController.php
    protected function credentials(Request $request)
        {
            return $request->only(
                'username', 'password', 'password_confirmation', 'token'
            );
        }
    
  7. 更新或覆盖getEmailForPasswordReset()中的Illuminate\Auth\Passwords\CanResetPassword.php方法,如下所示。

    public function getEmailForPasswordReset()
        {
            return $this->username;
        }
    
  8. Laravel使用键值对来查找用户并发送电子邮件。如果您通过'username => 'xyz',则会在'xyz'字段中查找值为username的第一条记录。

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

答案 1 :(得分:0)

  

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

然后,您需要重写此功能并向用户询问一些更独特的信息,无论它是什么。 Laravel提供密码重置,期望电子邮件是独一无二的,并且根据您当前的设计,它不会起作用。这里没有魔力。您无法使用非唯一数据消除歧义。

答案 2 :(得分:0)

您需要为此重做一些事情,但我觉得用户体验更好。为每个用户生成唯一键(用于数据隐藏)。有一种用于创建唯一键的辅助方法。

然后,当发送电子邮件时,将按钮链接到使用此密钥的路由。

然后,修改或创建指向重置密码控制器的路由。然后,您将知道它所指的是哪个用户。

无需用户插入密码,因为您已经知道密码是谁。