速率限制
簡介
Laravel 包含一個易於使用的速率限制抽象層,它與您的應用程式的快取結合使用,提供了一種簡單的方法來限制在指定時間範圍內的任何操作。
如果您對限制傳入的 HTTP 請求感興趣,請參閱速率限制器中介層文件。
快取設定
通常,速率限制器會使用您的應用程式快取設定檔中由 default
鍵定義的預設應用程式快取。但是,您可以在應用程式的 cache
設定檔中定義一個 limiter
鍵,來指定速率限制器應使用哪個快取驅動程式。
'default' => env('CACHE_STORE', 'database'), 'limiter' => 'redis',
基本用法
可以使用 Illuminate\Support\Facades\RateLimiter
外觀來與速率限制器互動。速率限制器提供的最簡單方法是 attempt
方法,它會針對給定的秒數限制給定回呼的速率。
當回呼沒有剩餘嘗試次數時,attempt
方法會傳回 false
;否則,attempt
方法將傳回回呼的結果或 true
。attempt
方法接受的第一個引數是速率限制器「鍵」,它可以是您選擇的任何字串,代表正在進行速率限制的操作。
use Illuminate\Support\Facades\RateLimiter; $executed = RateLimiter::attempt( 'send-message:'.$user->id, $perMinute = 5, function() { // Send message... }); if (! $executed) { return 'Too many messages sent!';}
如有必要,您可以向 attempt
方法提供第四個引數,即「衰減率」,或直到可用嘗試次數重置的秒數。例如,我們可以修改上面的範例,允許每兩分鐘嘗試五次。
$executed = RateLimiter::attempt( 'send-message:'.$user->id, $perTwoMinutes = 5, function() { // Send message... }, $decayRate = 120,);
手動增加嘗試次數
如果您想手動與速率限制器互動,可以使用各種其他方法。例如,您可以調用 tooManyAttempts
方法,以確定給定的速率限制器鍵是否已超過每分鐘允許的最大嘗試次數。
use Illuminate\Support\Facades\RateLimiter; if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) { return 'Too many attempts!';} RateLimiter::increment('send-message:'.$user->id); // Send message...
或者,您可以使用 remaining
方法來檢索給定鍵的剩餘嘗試次數。如果給定鍵有剩餘的重試次數,您可以調用 increment
方法來增加總嘗試次數。
use Illuminate\Support\Facades\RateLimiter; if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) { RateLimiter::increment('send-message:'.$user->id); // Send message...}
如果您想將給定速率限制器鍵的值增加一以上,可以將所需數量提供給 increment
方法。
RateLimiter::increment('send-message:'.$user->id, amount: 5);
確定限制器的可用性
當金鑰沒有剩餘嘗試次數時,availableIn
方法會傳回直到更多嘗試次數可用的剩餘秒數。
use Illuminate\Support\Facades\RateLimiter; if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) { $seconds = RateLimiter::availableIn('send-message:'.$user->id); return 'You may try again in '.$seconds.' seconds.';} RateLimiter::increment('send-message:'.$user->id); // Send message...
清除嘗試次數
您可以使用 clear
方法重置給定速率限制器鍵的嘗試次數。例如,您可以在接收者讀取給定訊息時重置嘗試次數。
use App\Models\Message;use Illuminate\Support\Facades\RateLimiter; /** * Mark the message as read. */public function read(Message $message): Message{ $message->markAsRead(); RateLimiter::clear('send-message:'.$message->user_id); return $message;}