Rate Limiting
Table of Contents
Introduction
Laravel は、application のcacheと連携することで、特定の時間窓内で任意の action を制限する簡単な方法を提供する、使いやすい rate limiting abstraction を含んでいます。
NOTE
もし rate limiting による受信 HTTP requests に興味があるならば、rate limiter middleware documentationをご参照ください。
Cache 設定
通常、レートリミッタは、アプリケーションのcache
設定ファイル内のdefault
キーで定義された default application cache を使用します。ただし、アプリケーションのcache
設定ファイル内にlimiter
キーを定義することで、レートリミッタが使用するべき cache driver を指定できます。
'default' => env('CACHE_STORE', 'database'),
'limiter' => 'redis',
Basic Usage
Illuminate\Support\Facades\RateLimiter
facade はレートリミッターと対話するために使用することができます。レートリミッターが提供する最もシンプルな method は、一定時間内でのコールバックのレート制限を行うattempt
method です。
attempt
method は、コールバックに残りの試行回数がない場合は false
を返します。それ以外の場合、attempt
method はコールバックの結果または true
を返します。attempt
method が受け入れる最初の引数は、レート制限される action を表す任意の string であるレートリミッターの "key" です。
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
method に第 4 引数を提供することができます。これは"ディケイレート"、または使用できる試行が reset されるまでの秒数を指します。例えば、上記の例を修正して 2 分ごとに 5 回の試行を許可するようにすることができます。
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perTwoMinutes = 5,
function() {
// Send message...
},
$decayRate = 120,
);
手動で試行回数を増やす
レートリミッターと手動でやり取りしたい場合、他にも様々な方法が利用可能です。例えば、特定のレートリミッターキーが許可された試行回数を 1 分間に超えているかどうかを判断するために、tooManyAttempts
method を呼び出すことができます:
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
method を使用することもできます。特定のキーが再試行を残している場合は、合計試行回数を increment するためにincrement
method を呼び出すことができます。
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
RateLimiter::increment('send-message:'.$user->id);
// Send message...
}
特定のレートリミッター key の value を 1 以上で増加させたい場合は、目的の量を increment
method に与えることができます。
RateLimiter::increment('send-message:'.$user->id, amount: 5);
リミッターの利用可能性の判断
キーの試行回数が残っていないとき、availableIn
method は、さらなる試行が可能になるまでの残り秒数を返します:
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...
クリア試行
指定された rate limiter key の試行回数を、clear
という method を使って reset することができます。例えば、特定のメッセージが受信者に読まれたときに試行回数を reset することもできます:
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;
}