回数の制限(レート制限)
「1分間に5回まで」のように、ある操作の回数を制限するレート制限の使い方を、attempt・increment・remaining・clear などの例で説明します。
レート制限は、ある操作ができる回数に、上限を決めるしくみです。たとえば「メッセージは1分間に5回まで」と決めておけば、連続で送りつけられるのを防げます。駅の自動改札で、同じ人が短い時間に何度も通れないようにするようなものです。
Laravel には、使いやすいレート制限の道具があります。アプリのキャッシュ(一度作った結果を取っておき、次から速く返すしくみ)と組み合わせて、決めた時間のあいだの回数を数えます。
補足
届いた HTTP のリクエストの回数を制限したいときは、ルーティングのページにある、レート制限のミドルウェア(リクエストが処理に届く前に、間に入って確かめる処理)を見てください。
キャッシュの設定#
レート制限は、ふつう、アプリの cache 設定ファイルの default で決めた、いつものキャッシュを使います。レート制限だけ別のキャッシュドライバー(キャッシュの保存先の種類)を使いたいときは、cache 設定ファイルに limiter というキーを書いて決めます。
'default' => env('CACHE_STORE', 'database'),
'limiter' => 'redis', // この行を足す
基本の使い方#
レート制限は、Illuminate\Support\Facades\RateLimiter ファサード(Route::get() のように、クラス名と :: で機能を呼べる窓口)で使います。いちばんかんたんなのは attempt メソッドです。決めた秒数のあいだ、渡した関数を動かせる回数を制限します。
attempt は、残りの回数がなくなると false を返します。残りがあれば、関数の結果か true を返します。1つ目の引数は、レート制限の「キー」です。何の操作を制限するかを表す、好きな文字を使えます。
use Illuminate\Support\Facades\RateLimiter;
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// Send message...
}
);
if (! $executed) {
return 'Too many messages sent!';
}
4つ目の引数に、「回復までの秒数」(decay rate)を渡せます。使える回数が、元に戻るまでの秒数です。たとえば、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...
同時にたくさんのリクエストが来る窓口では、tooManyAttempts と increment を別々に呼ばずに、increment が返す値を調べるとよいです。redis・memcached・database のキャッシュでは、数を増やす処理が、とちゅうで割りこまれない1回の操作として動きます。そのため、同時に来たリクエストにも、それぞれちがう数が返ります。
use Illuminate\Support\Facades\RateLimiter;
$perMinute = 5;
if (RateLimiter::increment('send-message:'.$user->id) > $perMinute) {
return 'Too many attempts!';
}
// 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回で、2以上増やしたいときは、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;
}
メソッドの一覧#
このページに出てきた RateLimiter のメソッドをまとめます。
| メソッド | 説明 |
|---|---|
attempt |
決めた秒数のあいだ、関数を動かせる回数を制限する。回数がなければ false |
tooManyAttempts |
そのキーが、上限を超えたかを調べる |
increment |
そのキーの回数を増やす(数を渡すと、その数だけ増やす)。増やしたあとの値を返す |
remaining |
そのキーの、残りの回数を調べる |
availableIn |
また使えるようになるまでの秒数を返す |
clear |
そのキーの回数を元に戻す |
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。