ざっくりまとめ
- Laravelには任意のエンドポイントに対してレートリミットを行うためのミドルウェアが用意されている
- 1分当たり10リクエストまで、という感じで制限可能
- ログイン中ならユーザ、そうでなければIPアドレス単位でカウントされる
レートリミットとは
1分間に10回まで実行してよい、みたいな感じで制限を課すこと。Web APIや高負荷な集計/エクスポート機能といった、必要だがむやみに連打されたくない機能で利用することが多い
Laravelには、レートリミット機能を提供するミドルウェアが標準で用意されている
あんまりドキュメントには情報がないのでコードを追った
参考にしたコードは、Laravel 6.5リリース時点のもの
実装的にはこの辺から: https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php
制限の単位
- https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php#L49
- ログイン時はログインユーザ単位
- 非ログイン時はIPアドレス単位
何分当たり何リクエストまで、という感じで指定可能
- https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php#L47
- "何分当たり" のところはfloatも利用可能なので、厳密ではないけど秒数でも指定可能
- https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php#L41
- 例えば1秒を指定したければ
1/60 = 0.0167
を指定する感じ
誰がどのぐらいリクエストしてきたかは内部的にはcacheで管理される
制限を超えると、ステータスコード429を返す
- https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php#L53
- https://github.com/laravel/framework/blob/v6.5.0/src/Illuminate/Routing/Middleware/ThrottleRequests.php#L115
- https://github.com/laravel/framework/blob/e04a7ffba8b80b934506783a7d0a161dd52eb2ef/src/Illuminate/Http/Exceptions/ThrottleRequestsException.php#L21
ユーザにこの画面を見せるわけにはいかないので、ちゃんと適切なエラーページを用意してあげよう
使い方
throttle:$何回まで,$何分間のうちに
みたいな感じでミドルウェアを指定すれば使える
公式ドキュメントに乗っている下記の例だと、1分間に60回までリクエストを許すという設定になる
Route::middleware('auth:api', 'throttle:60,1')->group(function () { Route::get('/user', function () { // }); });
61回目のリクエストからは 429 Too Many Requests
というエラーが表示される