[英]Laravel throttle rate limiter limites access too early
我正在使用 Laravel 5.8,我想應用一個速率限制器,將發送請求限制為每分鍾 500 個。
所以我嘗試將這個throttle
添加到路由組中:
Route::middleware('throttle:500,1')->group(function () {
...
});
所以這意味着限制在 1 分鍾內 500 個請求后訪問路由。
現在的問題是我得到429 | 太多的請求太快了!
我的意思是,它似乎不會在一分鍾內發送 500 個請求,但它會以某種方式限制訪問。
那么這里出了什么問題? 為什么我過早收到太多請求消息?
如果您有另一個油門組,油門中間件請求會一起計算,這些會一起計算,並且該組可能會消耗您的限制
Route::get('example1', function () {
return 'ans1';
})->middleware('throttle:5,1');
Route::get('example2', function () {
return 'ans2';
})->middleware('throttle:5,1');
在上面的例子中,你有 2 個路由,但是如果你向 example1 發送 2 個請求,向 example2 發送 3 個請求,你的速率限制將對它們都完成,你得到429 | 太多請求錯誤。
如果您在您的組中使用多個節流中間件並且它是這樣的嵌套路由:
Route::middleware('throttle:500,1')->group(function () {
Route::post('/foo', 'bar@foo')->middleware('throttle:5,60');
});
油門中間件對每個請求計數兩次。 為了解決這個問題,你必須確保每條路由只有一個油門中間件。
但有時即使中間件只使用了一次,請求計數仍然是錯誤的。 在這種情況下,您可以制作自己的自定義油門中間件,該中間件需要一個額外的參數來命名油門鍵並防止重新計算請求(基於this )。
為此,您必須首先創建一個中間件(根據this ):
php artisan make:middleware CustomThrottleMiddleware
然后,將內容替換為:
<?php
namespace App\Http\Middleware;
use Closure;
use RuntimeException;
use Illuminate\Routing\Middleware\ThrottleRequests;
class CustomThrottleMiddleware extends ThrottleRequests
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param int|string $maxAttempts
* @param float|int $decayMinutes
* @param string $keyAppend
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Http\Exceptions\ThrottleRequestsException
*/
public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1, $keyAppend = '')
{
$key = $this->resolveRequestSignature($request, $keyAppend);
$maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts);
if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
throw $this->buildException($key, $maxAttempts);
}
$this->limiter->hit($key, $decayMinutes * 60);
$response = $next($request);
return $this->addHeaders(
$response, $maxAttempts,
$this->calculateRemainingAttempts($key, $maxAttempts)
);
}
/**
* Resolve request signature.
*
* @param \Illuminate\Http\Request $request
* @param string $keyAppend
* @return string
*
* @throws \RuntimeException
*/
protected function resolveRequestSignature($request, $keyAppend='')
{
if ($user = $request->user()) {
return sha1($user->getAuthIdentifier().$keyAppend);
}
if ($route = $request->route()) {
return sha1($route->getDomain().'|'.$request->ip().$keyAppend);
}
throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
}
}
這樣做之后,您必須通過更新app/Http/Kernel.php
文件來注冊中間件:
protected $routeMiddleware = [
//...
'custom_throttle' => \App\Http\Middleware\CustomThrottleMiddleware::class,
];
現在你可以在你的路線中使用這個新的定制油門中間件,就像這樣:
Route::middleware('throttle:500,1')->group(function () {
Route::post('/foo', 'bar@foo')->middleware('custom_throttle:5,60,foo');
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.