php Laravel 6 ForgotPasswordController不发送重置邮件

vcirk6k6  于 2023-10-15  发布在  PHP
关注(0)|答案(1)|浏览(129)

我正在调试一个Laravel 6应用程序,它没有向用户发送密码重置电子邮件。应用程序发送的所有其他电子邮件工作正常,我已经尝试了不同的邮件服务器没有成功。应用程序不会在日志中抛出任何错误,并且如果输入了有效的电子邮件地址,则返回重置电子邮件已成功发送。
重置电子邮件应通过默认的ForgotPasswordController发送。只有sendResetLinkResponsesendResetLinkFailedResponse方法被修改为一些自定义JSON响应。

class ForgotPasswordController extends Controller
{
    use SendsPasswordResetEmails;

    protected function sendResetLinkResponse(Request $request, $response)
    {
        return response()->json([...], 200);
    }

    protected function sendResetLinkFailedResponse(Request $request, $response)
    {
        return response()->json([...], 422);
    }
}

端点调用SendsPasswortResetEmails trait中定义的sendResetLinkEmail函数。

/**
 * 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->validateEmail($request);

    // We will send the password reset link to this user. Once we have attempted
    // to send the link, we will examine the response then see the message we
    // need to show to the user. Finally, we'll send out a proper response.
    $response = $this->broker()->sendResetLink(
        $this->credentials($request)
    );

    return $response == Password::RESET_LINK_SENT
                ? $this->sendResetLinkResponse($request, $response)
                : $this->sendResetLinkFailedResponse($request, $response);
}

此函数的行为与预期的一样;使用有效的电子邮件地址,调用覆盖的sendResetLinkResponse方法。此外,生成数据库表password_resets中的条目。
User模型具有CanResetPasswordContractCanResetPassword trait,如文档中所述:https://laravel.com/docs/6.x/passwords。此外,User模型和数据库中的email列仅称为email
我在另一篇文章中读到.env中的MAIL_FROM属性可能会导致一些问题,但我认为这也不是我的问题,因为应用程序发送的所有其他电子邮件都工作正常。

MAIL_FROM_A[email protected]
MAIL_FROM_NAME="My Application"

我希望你能给我指出正确的方向来追踪这个问题。谢谢你,谢谢!

更新

在我深入研究了应用程序代码之后,我发现使用的通知实现了ShouldQueue。这就是为什么没有消息发送,也没有错误记录的原因。更多详情请看我下面的回复。

flmtquvp

flmtquvp1#

经过一番调查,我自己发现了错误。我想这个解决方案是不可推广的,但也许它可以帮助你们中的一些人朝着正确的方向搜索。
就像在最初的问题中描述的那样,sendResetLinkEmail函数是我的最后一站。这个函数使用的是facade Illuminate\Support\Facades\Password,而facade Illuminate\Contracts\Auth\PasswordBroker使用的是facade Illuminate\Support\Facades\Password

// Illuminate\Foundation\Auth\SendsPasswordResetEmails::sendResetLinkEmail()
$response = $this->broker()->sendResetLink(
    $this->credentials($request)
);

PasswordBroker具有以下功能:

// Illuminate\Auth\Passwords\PasswordBroker
/**
 * Send a password reset link to a user.
 *
 * @param  array  $credentials
 * @return string
 */
public function sendResetLink(array $credentials)
{
    // First we will check to see if we found a user at the given credentials and
    // if we did not we will redirect back to this current URI with a piece of
    // "flash" data in the session to indicate to the developers the errors.
    $user = $this->getUser($credentials);

    if (is_null($user)) {
        return static::INVALID_USER;
    }

    if (method_exists($this->tokens, 'recentlyCreatedToken') &&
        $this->tokens->recentlyCreatedToken($user)) {
        return static::RESET_THROTTLED;
    }

    // Once we have the reset token, we are ready to send the message out to this
    // user with a link to reset their password. We will then redirect back to
    // the current URI having nothing set in the session to indicate errors.
    $user->sendPasswordResetNotification(
        $this->tokens->create($user)
    );

    return static::RESET_LINK_SENT;
}

所以我看了一下:

// Illuminate\Auth\Passwords\CanResetPassword
/**
 * Send the password reset notification.
 *
 * @param  string  $token
 * @return void
 */
public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}

并注意到通过这一点,该通知ResetPasswordNotification发布和实施ShouldQueue .

class ResetPasswordNotification extends Notification implements ShouldQueue {}

因为没有队列工作线程在运行,所以密码重置通知从未发送,但这也是日志中没有错误的相同原因。

经验教训:在开始您的应用程序代码之旅之前,请先查看jobs表。

相关问题