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

Add extra question to Laravel forgotten password form and custom its error messages

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

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

我还想自定义错误消息,实际上不显示错误。例如,如果插入了无效的电子邮件,它不会显示错误消息 "We can't find a user with that e-mail address." 我不喜欢它,因为有人可能会通过尝试不同的电子邮件来猜测用户的电子邮件,直到 she/he 停止获取错误信息。相反,我想显示消息 "If the information provided is correct, you will receive an email with the link to reset your password."

如何将这些功能添加到Laravel auth?

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

请随意提出其他方法来达到预期的结果并使我的问题更清楚。非常感谢。

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

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

Laravel 创建的默认控制器 ForgotPasswordController 没有做太多事情。它所做的一切都在特征中。 trait 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

中的语言文件即可

希望对您有所帮助。

感谢用户@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);
    }

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

希望对大家有所帮助!!