在 Laravel 中禁用速率限制器?
Posted
技术标签:
【中文标题】在 Laravel 中禁用速率限制器?【英文标题】:Disable rate limiter in Laravel? 【发布时间】:2017-08-20 20:35:25 【问题描述】:有没有办法在 Laravel 中禁用每条/单个路由的速率限制?
我正在尝试测试一个接收大量请求的端点,但是 Laravel 会随机开始响应 status: 429, responseText: 'Too Many Attempts.'
来响应几百个请求,这使得测试非常痛苦。
【问题讨论】:
【参考方案1】:在app/Http/Kernel.php
Laravel 对所有 api 路由都有一个默认的油门限制。
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1',
],
];
评论或增加它。
【讨论】:
如果我评论是否意味着没有限制? 正确。注释掉意味着没有限制。 此方法强烈不建议使用,除非您的应用程序逻辑有特定的理由来更改限制。如果您想关闭节流以进行测试,请使用:$this->withoutMiddleware()->get($url, $data);
。
注释掉似乎并不意味着我最近的测试没有限制
有没有办法在达到限制后重置油门?我将系统日期更改为提前 2 个月进行测试,现在“Retry-After”响应 HTTP 标头表明我必须等待 2 个月才能访问 API 路由。【参考方案2】:
您实际上可以在测试中仅禁用某个中间件。
use Illuminate\Routing\Middleware\ThrottleRequests;
class YourTest extends TestCase
protected function setUp()
parent::setUp();
$this->withoutMiddleware(
ThrottleRequests::class
);
...
【讨论】:
这应该是公认的答案,因为这是测试此类内容的正确方法。全局禁用 Throttle 限制不是一个好习惯。 需要 Laravel 5.5+ 很好的答案,但是..关于在哪里以及如何使用此代码的更多信息呢?【参考方案3】:假设您正在使用 API 路由,那么您可以在 app/Http/Kernel.php 中更改节流阀或完全取消它。如果您需要限制其他路由,可以单独为它们注册中间件。
(以下示例:油门 - 60 次尝试然后锁定 1 分钟)
'api' => [
'throttle:60,1',
'bindings',
],
【讨论】:
【参考方案4】:您可以使用cache:clear
命令清除缓存,包括您的速率限制,如下所示:
php artisan cache:clear
【讨论】:
【参考方案5】:在 Laravel 5.7 中
动态速率限制 您可以根据已验证用户模型的属性指定动态请求最大值。例如,如果您的 User 模型包含 rate_limit 属性,您可以将属性名称传递给油门中间件,以便用于计算最大请求数:
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function ()
Route::get('/user', function ()
//
);
);
https://laravel.com/docs/5.7/routing#rate-limiting
【讨论】:
我在 Laravel 5.4 中尝试过,它确实有效,但由于某种原因,它使用了我输入的一半值。【参考方案6】:如果您只想为自动化测试禁用,您可以在测试中使用 WithoutMiddleware
特征。
use Illuminate\Foundation\Testing\WithoutMiddleware;
class YourTest extends TestCase
use WithoutMiddleware;
...
否则,只需从您的 Kernel 文件 (app/Http/Kernel.php
) 中删除 'throttle:60,1',
行,您的问题就会得到解决。
【讨论】:
【参考方案7】:您可以在app/Http/Kernel.php
中添加以下行
'api' => [
'throttle:120,1',
'bindings',
\App\Library\Cobalt\Http\Middleware\LogMiddleware::class,
],
如果问题仍然存在,请尝试使用 artisan 命令 php artisan cache:clear
【讨论】:
【参考方案8】:在单元测试中增加油门以避免可怕的 429 的非 hacky 方法:
-
从内核文件中间件中删除节流阀:60,1。
使用环境变量将油门中间件重新添加到路由组中:
$requestsPerMinute = ENV("REQUESTS_PER_MINUTE", 60);
Route::middleware(["auth:api", "throttle:$requestsPerMinute,1"])->group(function()
// your routes
);
-
在 phpunit.xml 中定义更高的 REQUESTS_PER_MINUTE 环境变量,以便在限制之前允许测试环境中的更多请求。
<server name="REQUESTS_PER_MINUTE" value="500"/>
-
(还要在 .env 中定义新的 REQUESTS_PER_MINUTE 变量,即使它会回落到 60)。
【讨论】:
【参考方案9】:如果您使用的是 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');
);
【讨论】:
不适用于 api 路由【参考方案10】:就我而言,我只是在 `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());
);
【讨论】:
以上是关于在 Laravel 中禁用速率限制器?的主要内容,如果未能解决你的问题,请参考以下文章