在 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 中禁用速率限制器?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 8速率限制器不适用于路线

Angular - http 拦截器 - http 速率限制器 - 滑动窗口

如何用 Java 来构建一个简单的速率限制器?

java 359.记录器速率限制器(#)。java

java 359.记录器速率限制器(#)。java

java 359.记录器速率限制器(#)。java