In this tutorial we are going learn how to rate limit your API requests in Laravel for better security of your application and prevention of DDos and Brute Force attack.
In Laravel we can do that with Laravel RateLimiter. To get started, we define rate limiter configurations within the configureRateLimiting method of your application's App\Providers\RouteServiceProvider class.
Rate limiters are defined using the RateLimiter facade's for method. The for method accepts a rate limiter name and a closure that returns the limit configuration that should apply to routes that are assigned to the rate limiter.
When the incoming request exceeds the specified rate limit, a response with a 429 HTTP status code will automatically be returned by Laravel. If we want add a custom response message that should be returned by a rate limit, we need to use the response method:
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
// protected $namespace = 'App\\Http\\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip())->response(function () {
return response(['messsage' => 'You have reached your access limit. Please try after 1 minute.'], 429);
});;
});
RateLimiter::for('posts', function (Request $request) {
return Limit::perMinute(5)->by(optional($request->user())->id ?: $request->ip())->response(function () {
return response(['messsage' => 'You have reached your access limit (Posts). Please try after 1 minute.'], 429);
});;
});
}
}
After we create the limiter then just need to bind it to our routes. We need to use the middleware function and we need to use throttle middleware. The naming convention should be throttle:name_of_the_limiter.
We can also directly limit a route during creation of route. The naming convention would be throttle:3,1 i.e. only 3 request is permissible per minute. It will return the default response and message. For custom message and response we need to create Custom rate limiter.
Route::middleware('throttle:posts')->get('/posts', [PostController::class, 'index']);
Route::middleware('throttle:3,1')->get('/posts/a', [PostController::class, 'index']);
0 Comments