【发布时间】:2017-08-20 20:35:25
【问题描述】:
有没有办法在 Laravel 中禁用每条/单个路由的速率限制?
我正在尝试测试一个接收大量请求的端点,但是 Laravel 会随机开始响应 { status: 429, responseText: 'Too Many Attempts.' } 来响应几百个请求,这使得测试非常痛苦。
【问题讨论】:
有没有办法在 Laravel 中禁用每条/单个路由的速率限制?
我正在尝试测试一个接收大量请求的端点,但是 Laravel 会随机开始响应 { status: 429, responseText: 'Too Many Attempts.' } 来响应几百个请求,这使得测试非常痛苦。
【问题讨论】:
在app/Http/Kernel.php Laravel 对所有 api 路由都有一个默认的油门限制。
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1',
],
];
评论或增加它。
【讨论】:
$this->withoutMiddleware()->get($url, $data);。
您实际上可以在测试中仅禁用某个中间件。
use Illuminate\Routing\Middleware\ThrottleRequests;
class YourTest extends TestCase
{
protected function setUp()
{
parent::setUp();
$this->withoutMiddleware(
ThrottleRequests::class
);
}
...
}
【讨论】:
假设您正在使用 API 路由,那么您可以在 app/Http/Kernel.php 中更改节流阀或完全取消它。如果您需要限制其他路由,可以单独为它们注册中间件。
(以下示例:油门 - 60 次尝试然后锁定 1 分钟)
'api' => [
'throttle:60,1',
'bindings',
],
【讨论】:
您可以使用cache:clear 命令清除缓存,包括您的速率限制,如下所示:
php artisan cache:clear
【讨论】:
在 Laravel 5.7 中
动态速率限制 您可以根据已验证用户模型的属性指定动态请求最大值。例如,如果您的 User 模型包含 rate_limit 属性,您可以将属性名称传递给油门中间件,以便用于计算最大请求数:
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
Route::get('/user', function () {
//
});
});
【讨论】:
如果您只想为自动化测试禁用,您可以在测试中使用 WithoutMiddleware 特征。
use Illuminate\Foundation\Testing\WithoutMiddleware;
class YourTest extends TestCase {
use WithoutMiddleware;
...
否则,只需从您的 Kernel 文件 (app/Http/Kernel.php) 中删除 'throttle:60,1', 行,您的问题就会得到解决。
【讨论】:
您可以在app/Http/Kernel.php 中添加以下行
'api' => [
'throttle:120,1',
'bindings',
\App\Library\Cobalt\Http\Middleware\LogMiddleware::class,
],
如果问题仍然存在,请尝试使用 artisan 命令 php artisan cache:clear
【讨论】:
在单元测试中增加油门以避免可怕的 429 的非 hacky 方法:
$requestsPerMinute = ENV("REQUESTS_PER_MINUTE", 60);
Route::middleware(["auth:api", "throttle:$requestsPerMinute,1"])->group(function(){
// your routes
});
<server name="REQUESTS_PER_MINUTE" value="500"/>
【讨论】:
如果您使用的是 Laravel 8.x 或更高版本,您可以通过以下步骤使用 RateLimiter:
在您的 app/Providers/RouteServiceProvider.php 中找到下面的 configureRateLimiting: 受保护的函数 configureRateLimiting() {
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
// no limit throttle
RateLimiter::for('none', function (Request $request) {
return Limit::none();
});
}
在你的 app/web.php 添加 'throttle:none:
Route::group(['middleware' => ['auth', 'throttle:none']], function ($router) {
Route::post('test', 'TestController@test');
});
【讨论】:
就我而言,我只是在 `App\Providers\RouteServiceProvider 中更改了 perMinute() 的默认值。
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
$perMinute = env('APP_ENV') === 'testing' ? 1000 : 60;
return Limit::perMinute($perMinute)
->by(optional($request->user())->id ?: $request->ip());
});
}
【讨论】: