繁体   English   中英

如何在Laravel 5.7中对排队的验证和密码重置通知电子邮件进行限速

[英]How to rate limit queued verification and password reset notification emails in laravel 5.7

问题

通过将Laravel 5.7与Redis一起使用,我已经获得了斯蒂芬·穆德雷(Stephen Mudere)的答案中描述的方法将电子邮件验证和密码重置通知排队,该方法在laravel 5如何使用队列通过电子邮件发送密码重置链接 ,但我不知道如何进行评分-限制那些特定的排队通知。 因为我的应用程序会出于多种原因(不仅是这两个目的)发送电子邮件,而且我的电子邮件服务器的速率限制为每分钟30封电子邮件,所以我需要对“电子邮件”队列中的所有内容进行速率限制。

背景

根据Laravel队列文档 ,使用handle方法在作业类中执行此操作似乎很简单

Redis::throttle('key')->allow(10)->every(60)->then(function () {
  // Job logic...
}, function () {
  // Could not obtain lock...

  return $this->release(10);
});

问题是我不是在使用作业类,而是在使用通知。 例如,对于密码重置,我创建了以下内容

ResetPassword Class
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;
}

使用以下方法从User模型中调用该方法:

public function sendPasswordResetNotification($token)
{
        $this->notify(new ResetPasswordNotification($token));
}

途径

我试图通过修改用户模型中的sendPasswordResetNotification函数来解决此问题:

public function sendPasswordResetNotification($token)
{
    Redis::throttle('email')->allow(2)->every(60)->then(function () use($token) {
        $this->notify(new ResetPasswordNotification($token));
    }, function () {
        // Could not obtain lock...

        return $this->release(10);
    });
}

请注意,出于测试目的,节气门的值人为地降低了。 这似乎部分起作用。 在上面的示例中,如果我尝试了两次连续的密码重置,则电子邮件将同时排队并发送。 当我尝试发送第三封电子邮件(超过我设置的每分钟2个限制)时,出现BadMethodCallException, "Call to undefined method App\\User::release()" 我知道这是因为User模型没有释放方法,但是又回到了我不确定确切在哪里或如何使用限制逻辑的问题。 有没有一种方法可以修改它以便工作,或者我需要采取一种完全不同的方法来发送这些消息吗?

更新:由于其他原因而失败的替代方法

我从使用通知切换为使用作业,以便可以根据文档使用Redis :: throttle。 为了设置作业以使消息排队,我使用了如何排队Laravel 5.7“电子邮件验证”电子邮件发送中的方法 这样可以很好地发送排队的电子邮件。 然后,我试图限制要排入队列的工作。 这是我完整的方法:

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Support\Facades\Redis;

class QueuedVerifyEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Redis::throttle('email')->allow(2)->every(60)->then(function () {
            $this->user->notify(new VerifyEmail);
        }, function() {
           return $this->release(10);
        });
    }
}

这些进入队列,但随后失败。 堆栈跟踪中的内容如下: Symfony\\Component\\Debug\\Exception\\FatalThrowableError: Class 'App\\Jobs\\Redis' not found in /home/vagrant/code/myapp/app/Jobs/QueuedVerifyEmail.php:27

当我有一个use语句来定义正确的位置时,我不知道为什么要在App \\ Jobs中寻找Redis外观。

我知道了

“更新:替代方法”下的解决方案最终起作用。 我不确定为什么它会失败(也许某些东西被缓存了?),但是现在看来它可以正常工作了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM