为什么请求被限制的时间比中间件中指定的时间长?

Why are requests throttled for more time than specified in the middleware?

我的路线声明如下:

Route::group(['prefix' => 'media', 'middleware' => 'auth'], function() {
    Route::group(['middleware' => 'throttle:120,1'], function() {
        Route::get('/', 'MediaController@index'); // <-- Route in question
        Route::delete('/{id}', 'MediaController@delete');
        Route::patch('/{id}', 'MediaController@edit');
    });
    Route::post('/', 'MediaController@upload')->middleware('throttle:100,1440');
});

如果我正确理解节流中间件,当用户达到速率限制(1 分钟内 120 个请求)时,他应该在 1 分钟的剩余时间内被节流,然后解除阻塞。

但是阻塞时间大于1分钟。参见 retry-after header:

(我第一次注意到它时,它超过了 600 秒,所以它并不总是 180 秒)

知道为什么会超过 1 分钟吗?

retry-afterheader与rate-limiting无关。所有与 rate-limiting 相关的 header 都以 x-ratelimit- 为前缀。 header x-ratelimit-reset 是您要查找的内容:重置限制的时间戳。这应该在下一分钟内(或您设置的任何时间段内)

我想通了!

原来 throttle 中间件的默认行为对每个路由不起作用。它只是限制每个登录用户的请求。如您所见,我有一条路线(上传路线)具有 throttle:100,1440,这导致问题导致 "punishments" 更长,即使对于 throttle:120,1 的路线也是如此。

我的解决方案: 我编写了自己的 ThrottleRequests.php 中间件版本,适用于每个路由:

  1. this file 放入您的 app/Http/Middleware 文件夹。
  2. app/Http/Kernel.php 中将你的 throttle 路由中间件更改为新的:
'throttle' => \App\Http\Middleware\ThrottleRequestsPerRoute::class,
  1. 现在,无论何时分配 throttle 中间件,它都会按路由工作。

另一个解决方案: 您还可以使用默认中间件并使用第三个参数。您可以像这样传递一个前缀参数:throttle:100,1440,upload。它会将上传前缀分配给节流键,并基于此对请求进行速率限制。但是,要实现每个路由的速率限制,您必须为每个路由分配不同的前缀。