簡體   English   中英

Laravel Rate Limiter 僅嘗試一次就錯誤地限制了訪問

[英]Laravel Rate Limiter Limits Access Wrongly After Only One Attempt

我正在使用 Laravel 5.8,我想設置一個速率限制器,限制每分鍾訪問路由以及 IP 地址。

所以我將其添加到RouteServiceProvider.php

protected function configureRateLimiting()
    {
        RateLimiter::for('limited', function (Request $request) {
            return [
                Limit::perMinute(500),
                Limit::perMinute(20)->by($request->ip()),
            ];
        });
    }

然后將其應用於路線:

Route::get("/", "StaticPages\HomeController@show")->middleware('throttle:limited')->name('home');

因此,它應該在從同一個 IP 地址嘗試 500 次或 20 次后限制訪問。

但現在的問題是它僅在一次嘗試后就顯示429 Too Many Requests

我不知道為什么只嘗試一次就限制訪問。

那么這里出了什么問題?

如何將基於 IP 地址的限制正確設置為每分鍾 20 和 500 個請求?

我相信您在嘗試在 Laravel 中實施請求速率限制器時閱讀了錯誤的文檔。“named throttle”僅從版本 8 開始引入。它在 5.8 版中不可用,請參閱該特定版本的laravel 文檔

如果您通過以下方式聲明油門:

 Route::get("/", "StaticPages\HomeController@show")->middleware('throttle:20,1')->name('home');

您可以在返回的 HTTP Header 上看到在第一次請求后說x-ratelimit-remaining 19。 因此,速率限制按預期工作。 但是,如果您設置throttle:limited ,它將無法理解它的含義並為x-ratelimit-remaining返回 -1 - 這就是為什么您可以打開一次頁面並為后續請求返回 HTTP 錯誤 429 的原因。

如果您對我的解釋仍有疑問,請在configureRateLimiting的開頭放置一個die()

protected function configureRateLimiting()
{
    die();
    RateLimiter::for('limited', function (Request $request) {
        return [
            Limit::perMinute(500),
            Limit::perMinute(20)->by($request->ip()),
        ];
    });
}

如果那個特定的 function 實際上是由 Laravel 執行的,你的應用程序應該在它可以響應任何請求之前停止工作。 如果不是,它會運行得很好。

此時,您只有 2 個選擇來實施您的速率限制器策略:1)實施您自己的速率限制器中間件; 2) 將您的 Laravel 至少更新到版本 8。

僅供參考,在Laravel文檔頁面的右上角,您可以設置要閱讀的文檔版本。

我認為您需要編寫代碼 [ return response('Custom response...', 429); ] 在函數中。

RateLimiter::for('limited', function (Request $request) {
    
    return Limit::perMinute(1000)->response(function () {
    return response('Custom response...', 429);

});

有關速率限制的更多信息:

https://laravel.com/docs/8.x/routing#rate-limiting

我同意@Bagus Tesa。 Laravel 5.8 throttle 中間件不接受除 max_rate 和 per_minutes 之外的參數。 Named rate limiting 在 Laravel 8 中引入,僅在 >= Laravel 8 版本中可用。 您可以實現自己的速率限制中間件或升級到 Laravel 8 以實現預期的功能。

參考: https://laravel.com/docs/5.8/routing#rate-limiting

嘗試 go 到 app\Http\Kernel.php 和配置,如果你使用 api: 'throttle:[max_rate],[per_minutes]'

'api' => [
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

或者嘗試覆蓋 function

protected function resolveRequestSignature($request)
    {
        if ($user = $request->user()) {
            return sha1($user->getAuthIdentifier());
        }

        if ($route = $request->route()) {
            return sha1($route->getDomain().'|'.$request->ip());
        }

    throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
}

仔細觀察這兩個 if 語句。 如果用戶在場,則節流鍵基於他們的用戶標識符。 如果用戶不存在,則標識符包括$request->ip() 來自不同 IP 地址的請求進入不同的限制桶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM