Laravel 5.4 - 覆盖 API 'throttle:60,1'
Laravel 5.4 - Override API 'throttle:60,1'
我正在写很多 API 来获取和存储数据。
我喜欢默认的 throttle
选项:
protected $middlewareGroups = [
'api' => [
'throttle:60,1',
'bindings',
],
];
将请求限制为每分钟 60 个;但是对于某些路线(es:POST
),我想增加这个值。
我尝试在路由中间件上设置 'throttle:500,1'
,如下所示:
Route::group(function () {
Route::get('semaphore/1', ['uses' => 'App\Api\V1\DBs\SemaphoreController@index']);
Route::post('semaphore/1', ['uses' => 'App\Api\V1\DBs\SemaphoreController@store', 'middleware' => 'WriteToDatabaseMiddleware', 'throttle:500,1']);
});
但它不起作用。
有什么想法吗?
谢谢。
更新:
我注意到 api.php
路由中使用的 'throttle:500,1'
将在 Kernel.php
文件中指定的默认 'throttle:60,1'
之后设置;然后,它不起作用。
记录进程执行,第一个调用是:
Illuminate\Routing\Middleware\ThrottleRequests -> handle
来自 Kernel.php
有 maxAttempts=60
.
那么,第二次调用是:
Illuminate\Routing\Middleware\ThrottleRequests -> handle
来自 api.php
有 maxAttempts=500
.
换句话说,api.php
文件中的 throttle:500,1
不会覆盖 Kernel.php
文件中的 throttle:60,1
。
当前答案
根据 this GitHub issue,节流中间件 不应 使用 "twice" (就像你想那样做)。只有两种方法可以解决你现在的问题"correctly":
- 编写自己的节流中间件
或
- 为每个路由(组)单独定义节流中间件
旧答案
您设置的中间件密钥有误!声明使用多个中间件时,为它们创建一个新数组
['middleware' => ['WriteToDatabaseMiddleware','throttle:500,1']]
编辑: 由于中间件的顺序,您应该将内核限制设置为您想要使用的最高值,并且所有其他路线应 比相应的路线具有更低的油门值 。
在 laravel 6 中,您可以使用前缀来防止全局限制。
使用 'throttle:5,1,prefix'
Route::group(['prefix' => 'contact-us', 'middleware' => 'throttle:5,1,contact-form',], function () {
Route::post('/', 'ContactUsController@store');
});
当前答案的 None 解释了 Laravel 5.x 行为。在该版本中,“throttle”的每个实例都使用相同的桶。因此,如果您在两个不同的位置放置节流命令,它会影响每个实例。
考虑:
// User can email 5 times an hour
Route::post('/email', 'Ctrl@email')->middleware('throttle:5,60');
// User can search 100 times an hour
Route::get('/search', 'Ctrl@search')->middleware('throttle:100,60);
如果用户在 5 分钟内搜索 5 次,他们将无法在接下来的一个小时内发送电子邮件。
在 Laravel 5.x 中没有办法解决这个问题。从 Laravel 6 开始 they added the ability to name throttles,给他们单独的桶。
我正在写很多 API 来获取和存储数据。
我喜欢默认的 throttle
选项:
protected $middlewareGroups = [
'api' => [
'throttle:60,1',
'bindings',
],
];
将请求限制为每分钟 60 个;但是对于某些路线(es:POST
),我想增加这个值。
我尝试在路由中间件上设置 'throttle:500,1'
,如下所示:
Route::group(function () {
Route::get('semaphore/1', ['uses' => 'App\Api\V1\DBs\SemaphoreController@index']);
Route::post('semaphore/1', ['uses' => 'App\Api\V1\DBs\SemaphoreController@store', 'middleware' => 'WriteToDatabaseMiddleware', 'throttle:500,1']);
});
但它不起作用。
有什么想法吗?
谢谢。
更新:
我注意到 api.php
路由中使用的 'throttle:500,1'
将在 Kernel.php
文件中指定的默认 'throttle:60,1'
之后设置;然后,它不起作用。
记录进程执行,第一个调用是:
Illuminate\Routing\Middleware\ThrottleRequests -> handle
来自 Kernel.php
有 maxAttempts=60
.
那么,第二次调用是:
Illuminate\Routing\Middleware\ThrottleRequests -> handle
来自 api.php
有 maxAttempts=500
.
换句话说,api.php
文件中的 throttle:500,1
不会覆盖 Kernel.php
文件中的 throttle:60,1
。
当前答案
根据 this GitHub issue,节流中间件 不应 使用 "twice" (就像你想那样做)。只有两种方法可以解决你现在的问题"correctly":
- 编写自己的节流中间件
或
- 为每个路由(组)单独定义节流中间件
旧答案
您设置的中间件密钥有误!声明使用多个中间件时,为它们创建一个新数组
['middleware' => ['WriteToDatabaseMiddleware','throttle:500,1']]
编辑: 由于中间件的顺序,您应该将内核限制设置为您想要使用的最高值,并且所有其他路线应 比相应的路线具有更低的油门值 。
在 laravel 6 中,您可以使用前缀来防止全局限制。
使用 'throttle:5,1,prefix'
Route::group(['prefix' => 'contact-us', 'middleware' => 'throttle:5,1,contact-form',], function () {
Route::post('/', 'ContactUsController@store');
});
None 解释了 Laravel 5.x 行为。在该版本中,“throttle”的每个实例都使用相同的桶。因此,如果您在两个不同的位置放置节流命令,它会影响每个实例。
考虑:
// User can email 5 times an hour
Route::post('/email', 'Ctrl@email')->middleware('throttle:5,60');
// User can search 100 times an hour
Route::get('/search', 'Ctrl@search')->middleware('throttle:100,60);
如果用户在 5 分钟内搜索 5 次,他们将无法在接下来的一个小时内发送电子邮件。
在 Laravel 5.x 中没有办法解决这个问题。从 Laravel 6 开始 they added the ability to name throttles,给他们单独的桶。