簡體   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