コンテンツへスキップ

レート制限

はじめに

Laravelには、アプリケーションのキャッシュと連携して、特定の時間枠内で任意のアクションを簡単に制限できる、使いやすいレート制限抽象化が含まれています。

lightbulb

着信HTTPリクエストのレート制限に興味がある場合は、レートリミッターミドルウェアのドキュメントを参照してください。

キャッシュ設定

通常、レートリミッターは、アプリケーションの`cache`設定ファイル内の`default`キーで定義されているデフォルトのアプリケーションキャッシュを使用します。ただし、アプリケーションの`cache`設定ファイル内に`limiter`キーを定義することで、レートリミッターが使用するキャッシュドライバーを指定できます。

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

基本的な使用方法

`Illuminate\Support\Facades\RateLimiter`ファサードを使用して、レートリミッターと対話できます。レートリミッターによって提供される最も簡単な方法は`attempt`メソッドで、これは指定された秒数に対して指定されたコールバックのレート制限を行います。

`attempt`メソッドは、コールバックに使用可能な試行回数が残っていない場合に`false`を返し、それ以外の場合はコールバックの結果または`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`メソッドに4番目の引数(「減衰率」または使用可能な試行回数がリセットされるまでの秒数)を提供できます。たとえば、上記の例を変更して、2分間に5回の試行を許可することができます。

$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perTwoMinutes = 5,
function() {
// Send message...
},
$decayRate = 120,
);

試行回数の増分(手動)

レートリミッターを手動で操作する必要がある場合は、さまざまなメソッドを使用できます。たとえば、`tooManyAttempts`メソッドを呼び出して、特定のレートリミッターキーが1分あたりの許容試行回数を超えているかどうかを確認できます。

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...
}

特定のレートリミッターキーの値を1回以上増やす場合は、`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;
}