17 April
Laravel
How to implement Rate Limiting in Laravel.
Limiting the number of requests per minute
sent to an application is often necessary to protect against attacks trying to saturate your server or
to brute force authentication forms. That’s why Laravel comes with a rate limiting mechanism,
which we will learn to use here.
There are two ways to implement rate limiting with Laravel:
1. Using the Rate Limiter Middleware: to rate limiting incoming HTTP
2. Using the Rate Limiting abstraction: to interact more finely with the rate limiter at the controller level
Get started
The throttle middleware is made to protect routes against excessive reception of too many HTTP requests and restricting them once a limit has been reached.
To get started, you should start by defining the rate limiter configurations
that your application needs. For that, go to the App\Providers\RouteServiceProvider class in the definition of the configureRateLimiting() method.
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\RateLimiter;
class RouteServiceProvider extends ServiceProvider
{
// ...
public function boot(): void
{
$this->configureRateLimiting();
// ...
}
/**
* Configure the rate limiters for the application.
*/
protected function configureRateLimiting(): void
{
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
}
}
In the above example, we have defined a rate limiter called global which limits
access to the routes associated with it to 1000 requests per minute.
You can create as many configurations as you want, with the names you want. We could for example imagine having global, downloads,
chat to customise the limit depending on the routes.
Once you defined your rate limiters, you can apply them to routes you want to rate limite using the throttle middleware, as follows:
Route::middleware(['throttle:global'])->group(function () {
Route::get('/products', [ProductController::class, 'index']);
Route::get('/products/{product}', [ProductController::class, 'show']);
Route::post('/products', [ProductController::class, 'store']);
});
Route::middleware(['throttle:downloads'])->group(function () {
Route::get('/reports/{report}/download', [ReportController::class, 'download']);
Route::get('/albums/{album}/download', [AlbumController::class, 'download']);
});
As you can see, you just need to pass a string containing throttle:
followed by the name of the rate limiter you have defined.
For these routes, if the rate limit is reached, the application will return a “429 — Too Many Requests”
response instead of serving the expected response.
Be aware! If your application has an API using the api middleware group, by default the throttles:api middleware is applied on these routes as defined in the $middlewareGroups['api']
property of your App\Http\Kernel class. So you have to define a rate limiter called api or to remove it from the group.
However, the RateLimiter is not only meant to be used with the throttle middleware,
you can also use it in a more advanced way in your controllers for example. I invite you to consult the documentation to learn more about this.
I hope you enjoyed this post.