Skip to content
Advertisement

Laravel Rate Limiter Limits Access Wrongly After Only One Attempt

I’m working with Laravel 5.8 and I wanted to set up a Rate Limiter that limits accessing to route by per minute and also IP address.

So I added this to RouteServiceProvider.php:

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

And then applied it to Route:

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

So it should be limiting access after 500 attempts or 20 attempts from the same IP address.

But now the problem is it shows 429 Too Many Requests after only ONE attempt!

I don’t know why it limits the access after only one attempt.

So what’s going wrong here?

How can I properly set the limitation based on IP address to 20 and 500 requests per minute?

Advertisement

Answer

I believe you’ve read the wrong documentation in your attempt to implement a request rate limiter in Laravel. The “named throttle” is only introduced starting version 8. It is unavailable on version 5.8, please see the laravel documentations for that particular version.

If you declared the throttle in the following way:

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

You can see on the returning HTTP Header saying x-ratelimit-remaining 19 after the first request. Hence, the rate limiting working as it supposed to be. However, if you put throttle:limited it would have no way understanding what does it meant and returns -1 for x-ratelimit-remaining – and thats why you can open the page once and return HTTP Error 429 for the subsequent requests.

If you still have doubts on my explanation, please put a die() at the beginning of the configureRateLimiting as such:

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

If that particular function is actually executed by Laravel, your app should stop working before it can answer any requests. If it isn’t, it will just run just fine.

At this point, you only have 2 options on implementing your rate limiter policy: 1) implement your own rate limiter middleware; 2) update your Laravel to at least version 8.

Fyi, on the top right corner of Laravel Documentation page, you can set which version of the documentation you want to read.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement