Laravel 仅尝试一次后,速率限制器错误地限制了访问
Laravel Rate Limiter Limits Access Wrongly After Only One Attempt
我正在与 Laravel 5.8 合作,我想设置一个速率限制器来限制每分钟访问路由以及 IP 地址。
所以我将其添加到 RouteServiceProvider.php
:
protected function configureRateLimiting()
{
RateLimiter::for('limited', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(20)->by($request->ip()),
];
});
}
然后应用到路线:
Route::get("/", "StaticPages\HomeController@show")->middleware('throttle:limited')->name('home');
因此它应该在从同一 IP 地址尝试 500 次或 20 次后限制访问。
但现在的问题是它仅在一次尝试后显示 429 请求过多!
不知道为什么只试了一次就限制访问
那么这里出了什么问题?
如何将基于 IP 地址的限制正确设置为每分钟 20 和 500 个请求?
我认为你需要编写代码 [return response('Custom response...', 429); ] 在函数中。
RateLimiter::for('limited', function (Request $request) {
return Limit::perMinute(1000)->response(function () {
return response('Custom response...', 429);
});
有关 rate-limiting 的更多信息:
我认为您在 Laravel 中尝试实施请求速率限制器时阅读了错误的文档。 “named throttle”仅从版本 8 开始引入。它在版本 5.8 上不可用,请参阅特定版本的 laravel documentations。
如果您通过以下方式声明油门:
Route::get("/", "StaticPages\HomeController@show")->middleware('throttle:20,1')->name('home');
您可以在 returning HTTP Header 上看到第一个请求后说 x-ratelimit-remaining
19。因此,速率限制按预期工作。但是,如果你输入 throttle:limited
它将无法理解它的含义,returns -1 表示 x-ratelimit-remaining
- 这就是为什么你可以打开页面一次并且 return 后续请求的 HTTP 错误 429。
如果你对我的解释还有疑问,请在configureRateLimiting
的开头加上一个die()
,这样:
protected function configureRateLimiting()
{
die();
RateLimiter::for('limited', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(20)->by($request->ip()),
];
});
}
如果该特定功能实际上由 Laravel 执行,您的应用程序应该在响应任何请求之前停止工作。如果不是,那就 运行 就好了。
此时,您只有 2 个选项来实施您的速率限制器策略:1) 实施您自己的速率限制器中间件; 2) 将您的 Laravel 至少更新到版本 8。
仅供参考,在Laravel文档页面的右上角,您可以设置要阅读的文档版本。
如果您使用的是 api,请尝试转至 app\Http\Kernel.php 并进行配置:
'throttle:[max_rate],[per_minutes]'
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
或尝试覆盖函数
protected function resolveRequestSignature($request)
{
if ($user = $request->user()) {
return sha1($user->getAuthIdentifier());
}
if ($route = $request->route()) {
return sha1($route->getDomain().'|'.$request->ip());
}
throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
}
仔细看看这两个 if 语句。如果用户在场,则节流键基于他们的用户标识符。如果用户不存在,则标识符包括 $request->ip()
。来自不同 IP 地址的请求进入不同的限制桶。
我同意@Bagus Tesa。 Laravel 5.8 throttle 中间件不接受除 max_rate 和 per_minutes 之外的参数。命名速率限制是在 Laravel 8 中引入的,并且仅在 >= Laravel 8 版本中可用。您可以实施自己的速率限制中间件或升级到 Laravel 8 以实现预期功能。
我正在与 Laravel 5.8 合作,我想设置一个速率限制器来限制每分钟访问路由以及 IP 地址。
所以我将其添加到 RouteServiceProvider.php
:
protected function configureRateLimiting()
{
RateLimiter::for('limited', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(20)->by($request->ip()),
];
});
}
然后应用到路线:
Route::get("/", "StaticPages\HomeController@show")->middleware('throttle:limited')->name('home');
因此它应该在从同一 IP 地址尝试 500 次或 20 次后限制访问。
但现在的问题是它仅在一次尝试后显示 429 请求过多!
不知道为什么只试了一次就限制访问
那么这里出了什么问题?
如何将基于 IP 地址的限制正确设置为每分钟 20 和 500 个请求?
我认为你需要编写代码 [return response('Custom response...', 429); ] 在函数中。
RateLimiter::for('limited', function (Request $request) {
return Limit::perMinute(1000)->response(function () {
return response('Custom response...', 429);
});
有关 rate-limiting 的更多信息:
我认为您在 Laravel 中尝试实施请求速率限制器时阅读了错误的文档。 “named throttle”仅从版本 8 开始引入。它在版本 5.8 上不可用,请参阅特定版本的 laravel documentations。
如果您通过以下方式声明油门:
Route::get("/", "StaticPages\HomeController@show")->middleware('throttle:20,1')->name('home');
您可以在 returning HTTP Header 上看到第一个请求后说 x-ratelimit-remaining
19。因此,速率限制按预期工作。但是,如果你输入 throttle:limited
它将无法理解它的含义,returns -1 表示 x-ratelimit-remaining
- 这就是为什么你可以打开页面一次并且 return 后续请求的 HTTP 错误 429。
如果你对我的解释还有疑问,请在configureRateLimiting
的开头加上一个die()
,这样:
protected function configureRateLimiting()
{
die();
RateLimiter::for('limited', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(20)->by($request->ip()),
];
});
}
如果该特定功能实际上由 Laravel 执行,您的应用程序应该在响应任何请求之前停止工作。如果不是,那就 运行 就好了。
此时,您只有 2 个选项来实施您的速率限制器策略:1) 实施您自己的速率限制器中间件; 2) 将您的 Laravel 至少更新到版本 8。
仅供参考,在Laravel文档页面的右上角,您可以设置要阅读的文档版本。
如果您使用的是 api,请尝试转至 app\Http\Kernel.php 并进行配置: 'throttle:[max_rate],[per_minutes]'
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
或尝试覆盖函数
protected function resolveRequestSignature($request)
{
if ($user = $request->user()) {
return sha1($user->getAuthIdentifier());
}
if ($route = $request->route()) {
return sha1($route->getDomain().'|'.$request->ip());
}
throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
}
仔细看看这两个 if 语句。如果用户在场,则节流键基于他们的用户标识符。如果用户不存在,则标识符包括 $request->ip()
。来自不同 IP 地址的请求进入不同的限制桶。
我同意@Bagus Tesa。 Laravel 5.8 throttle 中间件不接受除 max_rate 和 per_minutes 之外的参数。命名速率限制是在 Laravel 8 中引入的,并且仅在 >= Laravel 8 版本中可用。您可以实施自己的速率限制中间件或升级到 Laravel 8 以实现预期功能。