Laravel8以降では、処理実行レート制限機能が搭載されています。

この機能を利用して、一定期間内のアクセス数を制限する設定を施していきます。
これからやること
- Laravelプロジェクト新規作成
- レート制限設定
- ルーティング
- 動作確認
Laravelプロジェクト新規作成
新規プロジェクト「rate-limit」を作成します。
composer create-project laravel/laravel:^11 rate-limit

レート制限設定
「app\Providers\AppServiceProvider.php」を編集します。

冒頭に追記します。
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
「boot()」メソッドにレート制限の設定を記述します。
public function boot(): void
{
RateLimiter::for('top', function (Request $request) {
return Limit::perSecond(1)
->by($request->user()?->id ?: $request->ip());
});
}
※「top」は設定の名称で好きに設定できます。
※「Limit::perSecond(1)」で1秒に1回までの制限です。
※「by()」でクライアントを特定するキーを設定します。
※ユーザーIDか、またはIPアドレスで特定する設定です。
※複数のレート制限設定をする場合は次のように「RateLimiter::for()」を羅列すればOKです。
public function boot(): void
{
RateLimiter::for('top', function (Request $request) {
return Limit::perSecond(1)
->by($request->user()?->id ?: $request->ip());
});
RateLimiter::for('support', function (Request $request) {
return Limit::perHour(1)
->by($request->user()?->id ?: $request->ip());
});
RateLimiter::for('inquiry', function (Request $request) {
return Limit::perDay(1)
->by($request->user()?->id ?: $request->ip());
});
}
▼完成形
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
RateLimiter::for('top', function (Request $request) {
return Limit::perSecond(1)
->by($request->user()?->id ?: $request->ip());
});
}
}
ルーティング
ルーティングで、エンドポイント毎にレート制限設定を適用できます。
「routes/web.php」(APIの場合は「routes/api.php」)
を編集します。
※「->middleware([‘throttle:top’])」を追記
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
})->middleware(['throttle:top']);
※トップページ「/」に「top」のレート制限設定を適用
※エンドポイント毎に別のレート制限をする例は次のような感じです。
Route::get('/', function () {
return view('welcome');
})->middleware(['throttle:top']);
Route::get('/contact/support', function () {
return "サポート窓口です!";
})->middleware(['throttle:support']);
Route::get('/contact/inquiry', function () {
return "お問い合わせ内容をどうぞ!";
})->middleware(['throttle:inquiry']);
動作確認
ビルトインサーバーを起動します。
php artisan serve
WEBブラウザで http://localhost:8000/ にアクセスします。

設定が1秒間に1回までなので、1秒間に2回以上アクセスしてみます。
※F5(または[Ctrl]+R)を連打します。

「429 TOO MANY REQUESTS」が表示されました。
設定できるレート制限
「Illuminate\Cache\RateLimiting\Limit」
(vendor/laravel/framework/src/illuminate/Cache/RateLimiting/Limit.php)
内のメソッドを見ると次のようになっています。
| メソッド | 処理 |
|---|---|
| perSecond() | 1秒間の制限回数設定を返す |
| perMinute() | 1分間の制限回数設定を返す |
| perMinutes() | 指定分間の制限回数設定を返す |
| perHour() | 1時間の制限回数設定を返す |
| perDay() | 1日間の制限回数設定を返す |
| none() | 無制限設定を返す |
▼perSecond()
| 引数 | 型 | デフォルト | 例 | 説明 |
|---|---|---|---|---|
| $maxAttempts | int | 1 | 上限回数 | |
| $decaySeconds | int | 1 | 2 | 残りアクセス可能回数がリセットされるまでの秒数 |
▼perMinute()
| 引数 | 型 | デフォルト | 例 | 説明 |
|---|---|---|---|---|
| $maxAttempts | int | 12 | 上限回数 | |
| $decayMinutes | int | 1 | 2 | 残りアクセス可能回数がリセットされるまでの分数 |
※「$decayMinute」はPHPDoc上は「int」となっていますが、実装は型指定されていないので、「0.05」でも行けます。
/**
* Create a new rate limit.
*
* @param int $maxAttempts
* @param int $decayMinutes
* @return static
*/
public static function perMinute($maxAttempts, $decayMinutes = 1)
{
return new static('', $maxAttempts, 60 * $decayMinutes);
}
▼perMinutes()
| 引数 | 型 | デフォルト | 例 | 説明 |
|---|---|---|---|---|
| $decayMinutes | int | 2 | 残りアクセス回数がリセットされるまでの分数 | |
| $maxAttempts | int | 12 | 上限回数 |
※「perMinute(12, 2)」と「perMinutes(2, 12)」は同値です。
/**
* Create a new rate limit using minutes as decay time.
*
* @param int $decayMinutes
* @param int $maxAttempts
* @return static
*/
public static function perMinutes($decayMinutes, $maxAttempts)
{
return new static('', $maxAttempts, 60 * $decayMinutes);
}
▼perHour()
| 引数 | 型 | デフォルト | 例 | 説明 |
|---|---|---|---|---|
| $maxAttempts | int | 720 | 上限回数 | |
| $decayHours | int | 1 | 2 | 残りアクセス回数がリセットされるまでの時間数 |
※「$decayHours」はPHPDoc上は「int」ですが、実装は型指定されていないので、「0.005」でもいけます。
/**
* Create a new rate limit using hours as decay time.
*
* @param int $maxAttempts
* @param int $decayHours
* @return static
*/
public static function perHour($maxAttempts, $decayHours = 1)
{
return new static('', $maxAttempts, 60 * 60 * $decayHours);
}
▼perDay()
| 引数 | 型 | デフォルト | 例 | 説明 |
|---|---|---|---|---|
| $maxAttempts | int | 86400 | 上限回数 | |
| $decayDays | int | 1 | 2 | 残りアクセス数がリセットされるまでの日数 |
※「$decayDays」はPHPDoc上は「int」ですが、実装は型指定されていないので、「0.005」でもいけます。
/**
* Create a new rate limit using days as decay time.
*
* @param int $maxAttempts
* @param int $decayDays
* @return static
*/
public static function perDay($maxAttempts, $decayDays = 1)
{
return new static('', $maxAttempts, 60 * 60 * 24 * $decayDays);
}
▼none()
※引数なし
/**
* Create a new unlimited rate limit.
*
* @return static
*/
public static function none()
{
return new Unlimited;
}
※「Illuminate\Cache\RateLimiting\Unlimited」が返されます。
▼Illuminate\Cache\RateLimiting\Unlimited
<?php
namespace Illuminate\Cache\RateLimiting;
class Unlimited extends GlobalLimit
{
/**
* Create a new limit instance.
*
* @return void
*/
public function __construct()
{
parent::__construct(PHP_INT_MAX);
}
}
※実際はPHPの整数上限値「PHP_INT_MAX」が設定されています。
PHP_INT_MAX(int)この PHP がサポートする整数型の最大値。32bit のシステムでは 通常は int(2147483647)。 64bit のシステムでは、int(9223372036854775807)。
参考サイト


- 2
- 0
- 0
- 0

コメント