Lang x Lang

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

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use