# Laravel 429 Too Many Requests
Laravel のデフォルトでは1分以内に 60 回以上のリクエストを送信した場合、429Too Many Requests エラーが一定時間発生します。
# エラー解消するための対応
設定ファイル app/Http/kernel.php
protected $middlewareGroups = [
'api' => [
'throttle:120,1',
],
];
throttle に回数と期間(分)を指定すれば、解決します。
throttle function 内容
Illuminate/Routing/Middleware/ThrottleRequests.php
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param int|string $maxAttempts
* @param float|int $decayMinutes
* @param string $prefix
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Http\Exceptions\ThrottleRequestsException
*/
public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1, $prefix = '')
{
if (is_string($maxAttempts)
&& func_num_args() === 3
&& ! is_null($limiter = $this->limiter->limiter($maxAttempts))) {
return $this->handleRequestUsingNamedLimiter($request, $next, $maxAttempts, $limiter);
}
return $this->handleRequest(
$request,
$next,
[
(object) [
'key' => $prefix.$this->resolveRequestSignature($request),
'maxAttempts' => $this->resolveMaxAttempts($request, $maxAttempts),
'decayMinutes' => $decayMinutes,
'responseCallback' => null,
],
]
);
}
リクエスト元は、IP アドレスとドメインのハッシュキーから識別しているようで、
デフォルト設定では1分間に 60 回の最大値設定されています。
maxAttempts は最大の試行回数、decayMinutes は一定期間
# API 通信制御
429 エラーを解消するため制限を緩和することは簡単にできますが、フロントエンドで無駄な通信をやめて、lazy 通信や定期通信を選ぶのもあります。
lodash の debounce 使って一定時間止まったら実行させるとか、throttle で一定時間に 1 回ペースを実行させるとかやり方いろいろあります。
# 拡張
API リクエストの制限はデフォルト機能としてありますが、ユーザログインに一定期間内に失敗した回数カウントや同一 IP から一定期間内のアクセス管理にも同じ仕組みで使えそうです。