Custom Middleware for API Rate Limiting by Role in Laravel 11

Hello, laravel web developers! In this article, I'll show you how to implement custom middleware in Laravel 11 to rate-limit API requests based on user roles or other criteria. Whether you want to apply different limits for admins and regular users or handle high-traffic scenarios, this step-by-step guide will walk you through the process.

I'll also discuss how to manage rate limits effectively for high-traffic applications, ensuring your API remains responsive and secure.

Custom Middleware for API Rate Limiting by Role in Laravel 11

 

Step 1: Create Custom Middleware

First, let's create a new middleware for rate limiting. Run the following Artisan command to generate the middleware file:

php artisan make:middleware RoleBasedRateLimiter

This command will create a file in the app/Http/Middleware directory.

 

Step 2: Define the Middleware Logic

Open the generated RoleBasedRateLimiter.php file and modify it to define custom rate-limiting logic based on the user's role. Here's an example:

<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\RateLimiter;
use Closure;
use Illuminate\Http\Request;

class RoleBasedRateLimiter
{
    public function handle(Request $request, Closure $next)
    {
        $user = $request->user();

        // Check if the user is logged in and has a role
        if ($user && $user->role) {
            // Different rate limits based on roles
            if ($user->role === 'admin') {
                $this->setRateLimit($request, 'admin', 100, 1); // 100 requests per minute for admins
            } else {
                $this->setRateLimit($request, 'user', 60, 1); // 60 requests per minute for regular users
            }
        }

        return $next($request);
    }

    protected function setRateLimit(Request $request, $role, $maxAttempts, $decayMinutes)
    {
        RateLimiter::for($role, function () use ($request, $maxAttempts, $decayMinutes) {
            return Limit::perMinute($maxAttempts)->by(optional($request->user())->id ?: $request->ip());
        });

        // Check if the user has exceeded the rate limit
        if (RateLimiter::tooManyAttempts($role, optional($request->user())->id ?: $request->ip())) {
            return response()->json([
                'message' => 'Too many requests, please slow down.',
            ], 429);
        }
    }
}

 

Step 3: Register Middleware

Next, register your custom middleware in the bootstrap/app.php file.

<?php
  
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
  
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
  
        $middleware->alias([
            'role.rate.limit' => \App\Http\Middleware\RoleBasedRateLimiter::class,
        ]);
          
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

 

Step 4: Apply Middleware to Routes

Now that the middleware is created, let's apply it to specific API routes. Open the routes/api.php file and attach the middleware to routes like this:

Route::middleware(['auth:sanctum', 'role.rate.limit'])->group(function () {
    Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
    Route::get('/user/profile', [UserController::class, 'profile']);
});

 

Step 5: Testing the Middleware

You can now test the rate-limiting functionality by making API requests as different users. Try accessing the /admin/dashboard and /user/profile routes with admin and regular user roles, respectively. If you exceed the rate limits, the API will respond with a 429 Too Many Requests status.

 

Step 6: Handling High Traffic

For high-traffic applications, it's important to optimize the rate-limiting logic. Consider these best practices:

  • Cache Rate Limit Counters: Use Redis or Memcached to store rate limit counters, improving performance for large-scale applications.

  • Custom Rate Limiting by IP: If users aren’t logged in, rate limit by IP address to prevent abuse from unauthenticated users.

  • Monitoring and Alerts: Use tools like Laravel Horizon or external services like New Relic to monitor rate-limiting metrics and handle traffic spikes proactively.

 


You might also like:

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS