向 Laravel 忘记密码表单添加额外问题并自定义其错误消息

Posted

技术标签:

【中文标题】向 Laravel 忘记密码表单添加额外问题并自定义其错误消息【英文标题】:Add extra question to Laravel forgotten password form and custom its error messages 【发布时间】:2019-12-26 21:48:13 【问题描述】:

我想自定义 Laravel 中忘记密码的表单。

当要求重置密码时,用户除了插入他/她的电子邮件外,还必须回答一个简单的问题(您的第一只宠物的名字、您儿时最好的朋友的名字等)。这是为了避免其他人在知道帐户的电子邮件但不是帐户所有者的情况下要求重置密码。

我还想自定义错误消息,实际上不显示错误。例如,如果插入了无效的电子邮件,则不会显示错误消息“我们找不到具有该电子邮件地址的用户”。我不喜欢它,因为有人可能会通过尝试不同的电子邮件来猜测用户的电子邮件,直到她/他停止收到错误消息。相反,我想显示消息“如果提供的信息正确,您将收到一封电子邮件,其中包含重置密码的链接。”

如何将这些功能添加到 Laravel 身份验证中?

我正在寻找一种无需从头开始创建整个登录系统的解决方案(我认为,如果我尝试从头开始设计所有内容,我可能会遗漏一些东西并造成安全漏洞)。我想保留 Laravel 身份验证系统,只添加这两个功能。

请随意提出其他方法来实现预期结果并使我的问题更清楚。我会很感激的。

【问题讨论】:

可以尝试修改app/Http/Controllers/Auth/ForgotPasswordController.phpresources/views/auth/passwords/email.blade.php。如果您有任何错误,您可以打开一个显示您尝试过的代码的问题。 如果他们忘记了秘密问题怎么办? ;) "这是为了避免其他人在知道帐户的电子邮件但不是帐户所有者的情况下要求重置密码。"你为什么关心这个?是真的发生了,还是假设它可能会发生这些额外的麻烦? 假设它可能会发生,我会遇到所有这些额外的麻烦 :) 哈哈哈 @rits 我想他们不会忘记这个秘密问题。如果他们忘记了并且抱怨,那么我将删除多余的问题并返回之前的身份验证系统。这应该是一个简单的问题(比如,谁是你儿时最好的朋友?谁会忘记这个?),所以我想没有人会忘记答案 【参考方案1】:

感谢用户@Darryl E. Clarke,我设法解决了这个问题。这是我所做的:

在文件ForgotPasswordController的顶部,命名空间之后添加这一行:

use App\User;

在同一个文件中添加这3个方法:

    /**
     * Send a reset link to the given user.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    public function sendResetLinkEmail(Request $request)
    
        $this->validateRequest($request);

        // We will send the password reset link to this user. Regardless if that
        // worked, we will send the same response. We won't display error messages
        // That is because we do not want people guessing the users' email. If we
        // send an error message telling that the email is wrong, then a malicious
        // person may guess a user' email by trying until he/she stops getting that
        // error message.

        $user = User::whereEmail($request->email)->first();

        if ($user == null) 
            return $this->sendResponse();
        

        if ($user->secrete_question != $request->secrete_question) 
            return $this->sendResponse();
        

        $this->broker()->sendResetLink(
            $this->credentials($request)
        );

        return $this->sendResponse();
    

    /**
     * Validate the given request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function validateRequest(Request $request)
    
        $request->validate(['email' => 'required|email', 'secrete_question' => 'required|string']);
    

    /**
     * Get the response for a password reset link.
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendResponse()
    
        $response = 'If the information provided is correct, you will receive an email with a link to reset your password.';
        return back()->with('status', $response);
    

按照你想要的方式自定义它。

希望对他人有所帮助!!

【讨论】:

实际上,我认为这行得通,但事实并非如此。如果我能解决这个问题,我会更新答案 现在成功了!我更新了答案,它是正确的!【参考方案2】:

好消息是您不需要重写所有内容。

坏消息是,您需要了解特征以及如何扩展/覆盖它们,这可能有点令人困惑。

Laravel 创建的默认控制器 ForgotPasswordController 并没有做太多事情。它所做的一切都在特质中。特征SendsPasswordResetEmails 包含一些方法,最重要的是用于验证validateEmail 方法。

您可以使用检查已回答问题的方法覆盖此validateEmail 方法。您可以通过更改 'use' 语句来覆盖特征。

例如改变;

use SendsPasswordResetEmails

到:

use SendsPasswordResetEmails 
    validateEmail as originValidateEmail

这将告诉代码将原始方法 validateEmail 重命名为 originValidateEmail,从而允许您在自己的 ForgotPasswordController 中创建新的 validateEmail

然后,您可以在 ForgotPasswordController 内添加一个替换,该替换将由默认重置密码代码调用:

protected function validateEmail(Request $request)

    // add in your own validation rules, etc.
    $request->validate(['email' => 'required|email', 'questionfield' => 'required']);

要更改错误消息,您只需编辑resources/lang/en/passwords.php 中的语言文件

希望对您有所帮助。

【讨论】:

谢谢!!我会试一试,然后告诉你进展如何。 我做到了!谢谢!!

以上是关于向 Laravel 忘记密码表单添加额外问题并自定义其错误消息的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.5 自定义重置密码抛出令牌不匹配

Laravel - 如何在忘记密码中添加自定义字段

在 Laravel 中的令牌旁边添加电子邮件忘记密码模板电子邮件链接(已解决)

向 ModelAdmin 表单添加额外字段

向 Django 2.1 管理站点添加忘记密码功能

从 Laravel 中的数组向数据透视表中的额外列添加条件值