メインコンテンツまでスキップ

レート制限

はじめに

Laravel には、アプリケーションの キャッシュ と組み合わせて、指定された時間枠内での任意のアクションの制限を簡単に行うためのレート制限の抽象化が含まれています。

注記

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 メソッドに第四引数を提供することができます。これは「減衰率」または利用可能な試行回数がリセットされるまでの秒数です。たとえば、上記の例を変更して、2分ごとに5回の試行を許可するようにすることができます:

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

試行回数の手動増加

手動でレート制限装置とやり取りする場合、さまざまな他の方法が利用可能です。たとえば、与えられたレート制限キーが1分あたりの許可された試行回数を超えているかどうかを判断するために 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...
}

特定のレート制限キーの値を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;

/**
* メッセージを既読にする。
*/
public function read(Message $message): Message
{
$message->markAsRead();

RateLimiter::clear('send-message:'.$message->user_id);

return $message;
}