翻譯進度
47.73% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

頻率限制

簡介

Laravel includes a simple to use rate limiting abstraction which, in conjunction with your application's cache, provides an easy way to limit any action during a specified window of time.

lightbulb

If you are interested in rate limiting incoming HTTP requests, please consult the rate limiter middleware documentation.

快取設定

一般來說,Rate Limiter 會使用專案中 cache 設定檔 default 索引鍵上所定義的預設快取。不過,我們可以在專案的 cache 設定檔中定義 limiter 索引鍵來指定 Rate Limiter 要使用哪個快取 Driver:

1'default' => env('CACHE_STORE', 'database'),
2 
3'limiter' => 'redis',
1'default' => env('CACHE_STORE', 'database'),
2 
3'limiter' => 'redis',

基礎用法

可通過 Illuminate\Support\Facades\RateLimiter Facade 來使用 Rate Limiter。Rate Limiter 所提供的最簡單的方法是 attempt 方法,該方法會對給定閉包以給定秒數來做頻率限制。

若該回呼已無法再嘗試,則 attempt 方法會回傳 false。若還能繼續嘗試,則 attempt 會回傳該回呼的執行結果或 trueattempt 方法的第一個引數為 Rate Limiter 的「索引鍵」,索引鍵可以是任意字串,用來表示要被頻率限制的動作:

1use Illuminate\Support\Facades\RateLimiter;
2 
3$executed = RateLimiter::attempt(
4 'send-message:'.$user->id,
5 $perMinute = 5,
6 function() {
7 // Send message...
8 }
9);
10 
11if (! $executed) {
12 return 'Too many messages sent!';
13}
1use Illuminate\Support\Facades\RateLimiter;
2 
3$executed = RateLimiter::attempt(
4 'send-message:'.$user->id,
5 $perMinute = 5,
6 function() {
7 // Send message...
8 }
9);
10 
11if (! $executed) {
12 return 'Too many messages sent!';
13}

如有需要,可以為 attempt 方法提供第四個「Decay Rate」引數,或是直到頻率限制被重設前的秒數。例如,我們可以將上面的範例改為每 2 分鐘允許 5 次嘗試:

1$executed = RateLimiter::attempt(
2 'send-message:'.$user->id,
3 $perTwoMinutes = 5,
4 function() {
5 // Send message...
6 },
7 $decayRate = 120,
8);
1$executed = RateLimiter::attempt(
2 'send-message:'.$user->id,
3 $perTwoMinutes = 5,
4 function() {
5 // Send message...
6 },
7 $decayRate = 120,
8);

手動增加嘗試次數

若想手動使用 Rate Limiter,則還有其他許多能使用的方法。舉例來說,我們可以叫用 tooManyAttempts 方法來判斷給定的 Rate Limiter 索引鍵是否已遇到其每分鐘所允許的最大嘗試次數:

1use Illuminate\Support\Facades\RateLimiter;
2 
3if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
4 return 'Too many attempts!';
5}
6 
7RateLimiter::increment('send-message:'.$user->id);
8 
9// Send message...
1use Illuminate\Support\Facades\RateLimiter;
2 
3if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
4 return 'Too many attempts!';
5}
6 
7RateLimiter::increment('send-message:'.$user->id);
8 
9// Send message...

Alternatively, you may use the remaining method to retrieve the number of attempts remaining for a given key. If a given key has retries remaining, you may invoke the increment method to increment the number of total attempts:

1use Illuminate\Support\Facades\RateLimiter;
2 
3if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
4 RateLimiter::increment('send-message:'.$user->id);
5 
6 // Send message...
7}
1use Illuminate\Support\Facades\RateLimiter;
2 
3if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
4 RateLimiter::increment('send-message:'.$user->id);
5 
6 // Send message...
7}

If you would like to increment the value for a given rate limiter key by more than one, you may provide the desired amount to the increment method:

1RateLimiter::increment('send-message:'.$user->id, amount: 5);
1RateLimiter::increment('send-message:'.$user->id, amount: 5);

判斷 Limiter 是否可用

若某個索引鍵已無可用的嘗試次數,則 availableIn 方法會回傳距離下次可獲得嘗試次數的剩餘秒數:

1use Illuminate\Support\Facades\RateLimiter;
2 
3if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
4 $seconds = RateLimiter::availableIn('send-message:'.$user->id);
5 
6 return 'You may try again in '.$seconds.' seconds.';
7}
8 
9RateLimiter::increment('send-message:'.$user->id);
10 
11// Send message...
1use Illuminate\Support\Facades\RateLimiter;
2 
3if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
4 $seconds = RateLimiter::availableIn('send-message:'.$user->id);
5 
6 return 'You may try again in '.$seconds.' seconds.';
7}
8 
9RateLimiter::increment('send-message:'.$user->id);
10 
11// Send message...

清除嘗試次數

可使用 clear 方法來重設給定 Rate Limiter 索引鍵的嘗試次數。舉例來說,我們可以在收件人已閱讀某個訊息後重設嘗試次數:

1use App\Models\Message;
2use Illuminate\Support\Facades\RateLimiter;
3 
4/**
5 * Mark the message as read.
6 */
7public function read(Message $message): Message
8{
9 $message->markAsRead();
10 
11 RateLimiter::clear('send-message:'.$message->user_id);
12 
13 return $message;
14}
1use App\Models\Message;
2use Illuminate\Support\Facades\RateLimiter;
3 
4/**
5 * Mark the message as read.
6 */
7public function read(Message $message): Message
8{
9 $message->markAsRead();
10 
11 RateLimiter::clear('send-message:'.$message->user_id);
12 
13 return $message;
14}
翻譯進度
47.73% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.