Laravel Too Many Login Attempts: Restrict and Customize

Tutorial last revisioned on August 22, 2022 with Laravel 9

One of the less-known Laravel features is Login throttling. By default, if user tries to log in via default Laravel login form more than 5 times per minute, they will get different error message.

too many logins

Yes, the error isn't just “wrong password”. It's “Too many login attempts. Please try again in X seconds.”

By default, that X is 60, so Laravel restricts login attempts for one minute. But you can customize it.

Laravel Breeze

Breeze tries to authenticate the user in the App/Http/Requests/Auth/LoginRequest.php class, in the authenticate() method. In this method, there is a line that hits RateLimiter.

RateLimiter::hit($this->throttleKey());

If you check https://github.com/laravel/framework/blob/master/src/Illuminate/Cache/RateLimiter.php file where hit method is located, you will see that it accepts the second parameter decaySeconds which defaults to 60 seconds. So to change that time, you just need to pass your desired time as the second parameter in LoginRequest.php file. For example, if you want to limit it for 120s, it would be.

RateLimiter::hit($this->throttleKey(), 120);

That's all about the time limit, but what about limiting how many attempts? Well, it's also very easy. If we look at the same LoginRequest.php, in the ensureIsNotRateLimited method there is this very first line

if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {

This simple if condition just checks if user hasn't hit the limit. And that number 5 is the count of how many attempts a user can make. Just change that number to whatever you need.

Laravel Jetstream

Jetstream uses Laravel Fortify for handling authentication. If you open app\Providers\FortifyServiceProvider.php, in the boot method you should immediately see RateLimiter for login. Specifically this line:

return Limit::perMinute(5)->by($email.$request->ip());

By default, as in other starter kits, it's 5 times per minute, which you can change here. If you want to change the time, Limit has more methods than perMinute. You can find them and check what parameters they take in the official laravel GitHub repository here https://github.com/laravel/framework/blob/master/src/Illuminate/Cache/RateLimiting/Limit.php

Laravel UI

In your app/Http/Controllers/Auth/LoginController.php, you need to overwrite default values by adding two properties:

class LoginController extends Controller
{
protected $maxAttempts = 3; // Default is 5
protected $decayMinutes = 2; // Default is 1
// ...
}

These properties will override the defaults, so you can specify fewer/more attempts allowed per minute, and shorter/longer restriction time.

Notice: The throttling is unique to the user's username / e-mail address and their IP address.

avatar

How to rate limit user registrations (not logins) in Jetstream? This does not seem to work:

RateLimiter::for('register', function (Request $request) { return Limit::perMinute(1)->by($request->email.$request->ip()); });

Thanks.

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 57 courses (1055 lessons, total 46 h 42 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials