
How Does Laravel Rate Limiting Work?
Laravel Rate Limiting is a feature provided by the Laravel framework that allows developers to restrict the number of requests made to an endpoint or route in a given time frame. This is useful in preventing abuse of your application’s resources by limiting the number of requests a user can make in a certain period of time. In this tutorial, we will cover what Laravel Rate Limiting is, how it works, and some notes to keep in mind when using it.
What is Laravel Rate Limiting?
Laravel Rate Limiting is a middleware that can be added to any route or endpoint in your Laravel application. The middleware will track the number of requests made to that endpoint and will limit the number of requests a user can make in a certain time frame. This can help prevent abuse of your application’s resources by limiting the number of requests a user can make in a given period of time.
How Does Laravel Rate Limiting Work?
Laravel Rate Limiting works by tracking the number of requests made to a specific endpoint or route in a given time frame. This time frame can be customized, but the default is one minute.
When a user makes a request to an endpoint or route with the Rate Limiting middleware enabled, Laravel will check if the user has exceeded the limit for that time frame. If the user has exceeded the limit, Laravel will return a 429 Too Many Requests error.
By default, Laravel Rate Limiting tracks requests on a per-IP basis. This means that if a user makes multiple requests from the same IP address, Laravel will track those requests as coming from the same user. However, you can customize the way Laravel tracks requests by implementing your own store.
Notes to Keep in Mind When Using Laravel Rate Limiting
When using Laravel Rate Limiting, there are a few things to keep in mind:
- Customizing the time frame: By default, Laravel Rate Limiting tracks requests on a per-minute basis. However, you can customize this time frame by passing a second argument to the
throttle
method in your middleware. - Implementing your own store: Laravel Rate Limiting stores requests in a cache store by default. However, you can implement your own store by extending the
Illuminate\Cache\RateLimiting\Limit
class and passing it to thethrottle
method in your middleware. - Handling errors: When a user exceeds the rate limit, Laravel will return a 429 Too Many Requests error. You can customize how this error is handled by catching the
Illuminate\Http\Exceptions\ThrottleRequestsException
exception in your exception handler. - Rate limiting specific routes: You can add the Rate Limiting middleware to specific routes by adding it to the middleware stack for that route in your
web.php
file.
Advanced Examples
Here are some advanced examples of how you can use Laravel Rate Limiting in your application:
Rate Limiting API Endpoints
You can use Laravel Rate Limiting to rate limit API endpoints in your application. For example, if you have an API endpoint that allows users to make a certain number of requests per minute, you can use the Rate Limiting middleware to enforce this limit.
Route::middleware('throttle:10,1')->group(function () {
Route::get('/api/endpoint', function () {
// Your API endpoint logic here
});
});
In this example, we are rate limiting the /api/endpoint
route to 10 requests per minute. If a user exceeds this limit, Laravel will return a 429 Too Many Requests error.
Rate Limiting Authentication Requests
You can use Laravel Rate Limiting to rate limit authentication requests in your application. For example, if you have an authentication endpoint that allows users to make a certain number of login attempts per minute, you can use the Rate Limiting middleware to enforce this limit.
Route::post('/login', function (Request $request) {
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('dashboard');
}
// Increment the login attempts for the user
RateLimiter::hit($request->ip());
// Return a 429 Too Many Requests error if the user has exceeded the limit
throw ThrottleRequestsException::create($retryAfter);
});
In this example, we are using the RateLimiter
facade to increment the login attempts for the user. If the user exceeds the rate limit, Laravel will throw a ThrottleRequestsException
, which we can catch in our exception handler and return a 429 Too Many Requests error.
Rate Limiting API Requests by User
By default, Laravel Rate Limiting tracks requests on a per-IP basis. However, you can customize the way Laravel tracks requests by implementing your own store. This allows you to rate limit API requests on a per-user basis.
Route::middleware('throttle:user')->group(function () {
Route::get('/api/endpoint', function () {
// Your API endpoint logic here
});
});
In this example, we are using a custom store to rate limit API requests on a per-user basis. The user
parameter tells Laravel to use our custom store to track requests.
class UserStore extends Store
{
public function hit($key, $decaySeconds = 60)
{
$user = auth()->user();
if ($user) {
$key .= ':' . $user->id;
}
return parent::hit($key, $decaySeconds);
}
}
In this example, we are implementing our own store by extending the Illuminate\Cache\RateLimiting\Store
class. Our store uses the authenticated user’s ID to track requests on a per-user basis.
$this->app->singleton('cache', function ($app) {
return Cache::store('user-rate-limiting');
});
$this->app->bind(Store::class, UserStore::class);
In this example, we are binding our custom store to the Store
interface in the Laravel service container. We are also binding the cache
instance to use our custom store.
Rate Limit for only success requests
use Illuminate\Support\Facades\RateLimiter;
class CodeZiDotProTestRateLimit extends Controller
{
public function test_rate_limit_only_success(Request $request){
// Step 1: Validate the request data
$validator = Validator::make($request->all(), [
'name' => 'required|string',
'email' => 'required|email',
'password' => 'required|min:8',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
// Step 2: Apply rate limiting to this controller action
$key = 'test_rate_limit_only_success_by_ip_'.request()->ip();
if (RateLimiter::tooManyAttempts($key,10)) {
return response()->json(['errors' => 'You have made too much in a short time. Please wait after 1 minute'], 422);
} else {
RateLimiter::hit($key, 60);
}
}
}
Suppose my URL is Example.com/test_Rate_Limit_only_success.
In this example, when a user sends a request to the system, the application will still validate the request (and if there are errors, the user will send unlimited requests). In the case of valid data, the rate limiting part will start working.
By using a custom store, we can rate limit API requests on a per-user basis, which can be useful for applications that require more fine-grained rate limiting.