如何使用 laravel 5 中的队列通过电子邮件发送密码重置 link
How to send the password reset link via email using queue in laravel 5
我正在使用 laravel 的 ResetsPasswords 特征来实现密码重置。我想要实现的是使用队列发送电子邮件。深入研究代码,我在函数 postEmail():
中找到了以下行
$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject($this->getEmailSubject());
});
进一步挖掘,我注意到 sendResetLink() 函数是在 PasswordBroker class 中实现的,后者又调用函数 emailResetLink()。 emailResetLink 函数 returns 如下:
return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
我可以简单地将 mailer->send
更改为 mailer->queue
。在不修改这个非项目文件的情况下,他们有更好的方法吗?
这就是 Laravel 容器派上用场的地方。如果您不喜欢核心组件的功能,那么您可以继续并相当轻松地覆盖它。
首先,您需要创建自己的 PasswordBroker:
namespace App\Auth\Passwords;
use Illuminate\Auth\Passwords\PasswordBroker as IlluminatePasswordBroker;
class PasswordBroker extends IlluminatePasswordBroker
{
public function emailResetLink()
{
$view = $this->emailView;
return $this->mailer->queue($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
if (! is_null($callback)) {
call_user_func($callback, $m, $user, $token);
}
});
}
}
如果您想将命名空间放置在您应用的其他位置,请将您的命名空间更改为您想要的任何名称。
由于注册服务的服务提供商是 deferred service provider 您需要创建自己的提供商来替换它。可能最简单的方法是使用如下内容扩展 Illuminate\Auth\Passwords\PasswordResetServiceProvider
:
namespace App\Providers;
use App\Auth\Passwords\PasswordBroker;
class PasswordResetServiceProvider extends \Illuminate\Auth\Passwords\PasswordResetServiceProvider
{
protected function registerPasswordBroker()
{
$this->app->singleton('auth.password', function ($app) {
$tokens = $app['auth.password.tokens'];
$users = $app['auth']->driver()->getProvider();
$view = $app['config']['auth.password.email'];
return new PasswordBroker(
$tokens, $users, $app['mailer'], $view
);
});
}
}
最后在您的 config/app.php
文件中删除 Illuminate\Auth\Passwords\PasswordResetServiceProvider::class
并将 App\Providers\PasswordResetServiceProvider::class
添加到您的 'providers'
数组。
Laravel 现在将使用您的 PasswordBroker 实现而不是现有框架,您不必担心修改框架代码。
我知道这个问题已经得到解答,但我发现了另一种排队密码重置通知的方法,我发现它更简单。我已经在 Laravel 5.3 和 6.x.
上进行了测试
默认情况下,密码重置通知由Illuminate\Auth\Notifications\ResetPassword
class实现。此 class 在 User
模型中的 sendPasswordResetNotification
方法中实例化并传递给 Illuminate\Notifications\Notifiable
特征的 notify
方法。
因此,要排队密码重置通知,您只需通过 artisan make:notification ResetPassword
创建新的 ResetPassword
通知 class 并将其代码替换为:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;
class ResetPassword extends ResetPasswordNotification implements ShouldQueue
{
use Queueable;
}
现在只需覆盖 App\User
class:
中的 sendPasswordResetNotification
方法
<?php
...
use App\Notifications\ResetPassword as ResetPasswordNotification;
...
/**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
如果您在尝试指定队列 fakemeta 的解决方案后得到 "Call to a member function onQueue() on null",只需在 class.
的构造函数中指定您要定位的队列
<?php
namespace App;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class ResetPasswordNotification extends ResetPassword implements ShouldQueue
{
use Queueable;
public function __construct()
{
$this->queue = "authentication";
}
}
然后使用通知外观在覆盖方法中发送您的邮件。通知方法也有效
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\ResetPasswordNotification;
class User extends Authenticatable
{
public function sendPasswordResetNotification($token)
{
// either of the two work
// $this->notify(new ResetPasswordNotification($token));
\Notification::send($this, new ResetPasswordNotification($token));
}
}
我正在使用 laravel 的 ResetsPasswords 特征来实现密码重置。我想要实现的是使用队列发送电子邮件。深入研究代码,我在函数 postEmail():
中找到了以下行$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject($this->getEmailSubject());
});
进一步挖掘,我注意到 sendResetLink() 函数是在 PasswordBroker class 中实现的,后者又调用函数 emailResetLink()。 emailResetLink 函数 returns 如下:
return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
我可以简单地将 mailer->send
更改为 mailer->queue
。在不修改这个非项目文件的情况下,他们有更好的方法吗?
这就是 Laravel 容器派上用场的地方。如果您不喜欢核心组件的功能,那么您可以继续并相当轻松地覆盖它。
首先,您需要创建自己的 PasswordBroker:
namespace App\Auth\Passwords;
use Illuminate\Auth\Passwords\PasswordBroker as IlluminatePasswordBroker;
class PasswordBroker extends IlluminatePasswordBroker
{
public function emailResetLink()
{
$view = $this->emailView;
return $this->mailer->queue($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
if (! is_null($callback)) {
call_user_func($callback, $m, $user, $token);
}
});
}
}
如果您想将命名空间放置在您应用的其他位置,请将您的命名空间更改为您想要的任何名称。
由于注册服务的服务提供商是 deferred service provider 您需要创建自己的提供商来替换它。可能最简单的方法是使用如下内容扩展 Illuminate\Auth\Passwords\PasswordResetServiceProvider
:
namespace App\Providers;
use App\Auth\Passwords\PasswordBroker;
class PasswordResetServiceProvider extends \Illuminate\Auth\Passwords\PasswordResetServiceProvider
{
protected function registerPasswordBroker()
{
$this->app->singleton('auth.password', function ($app) {
$tokens = $app['auth.password.tokens'];
$users = $app['auth']->driver()->getProvider();
$view = $app['config']['auth.password.email'];
return new PasswordBroker(
$tokens, $users, $app['mailer'], $view
);
});
}
}
最后在您的 config/app.php
文件中删除 Illuminate\Auth\Passwords\PasswordResetServiceProvider::class
并将 App\Providers\PasswordResetServiceProvider::class
添加到您的 'providers'
数组。
Laravel 现在将使用您的 PasswordBroker 实现而不是现有框架,您不必担心修改框架代码。
我知道这个问题已经得到解答,但我发现了另一种排队密码重置通知的方法,我发现它更简单。我已经在 Laravel 5.3 和 6.x.
上进行了测试默认情况下,密码重置通知由Illuminate\Auth\Notifications\ResetPassword
class实现。此 class 在 User
模型中的 sendPasswordResetNotification
方法中实例化并传递给 Illuminate\Notifications\Notifiable
特征的 notify
方法。
因此,要排队密码重置通知,您只需通过 artisan make:notification ResetPassword
创建新的 ResetPassword
通知 class 并将其代码替换为:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;
class ResetPassword extends ResetPasswordNotification implements ShouldQueue
{
use Queueable;
}
现在只需覆盖 App\User
class:
sendPasswordResetNotification
方法
<?php
...
use App\Notifications\ResetPassword as ResetPasswordNotification;
...
/**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
如果您在尝试指定队列 fakemeta 的解决方案后得到 "Call to a member function onQueue() on null",只需在 class.
的构造函数中指定您要定位的队列<?php
namespace App;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class ResetPasswordNotification extends ResetPassword implements ShouldQueue
{
use Queueable;
public function __construct()
{
$this->queue = "authentication";
}
}
然后使用通知外观在覆盖方法中发送您的邮件。通知方法也有效
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\ResetPasswordNotification;
class User extends Authenticatable
{
public function sendPasswordResetNotification($token)
{
// either of the two work
// $this->notify(new ResetPasswordNotification($token));
\Notification::send($this, new ResetPasswordNotification($token));
}
}