Codepen Blog
  • Home
  • About us
  • Contact us
Codepen Blog
  • Home
  • About us
  • Contact us
Tuesday, February 3, 2026
Top Posts
Top 10 AI Logo Generators in 2023 with the Majority Being...
Ultimate Guide to install and setup WordPress multisite
Upload WordPress From localhost to live server in 2024
Top 10 Best WordPress Themes for Woocommerce in 2024
Top 11 WordPress Mobile Plugin for Optimal Usage in 2024
The Ultimate Guide to Self-Hosted WordPress Website
Creating a Complete Homepage Using Divi AI – Step by Step...
SSH-ing into a Docker container: a step-by-step guide
How to use ftp or sftp server to transfer files in...
Top 5 hosting to WordPress Staging Site with plugins in 2024
SUBSCRIBE NEWSLETTERS
Codepen Blog
Codepen Blog
  • Contact us
Copyright 2021 - All Right Reserved
Blogs

Mastering Laravel API Rate Limiting to Secure Endpoints

by developershohel August 15, 2023
written by developershohel August 15, 2023 Pay Writer
Mastering Laravel API Rate Limiting to Secure Endpoints
472

1. Introduction: Why Laravel API Rate Limiting Matters

In today’s API-driven world, protecting your endpoints from abuse is not just good practice—it’s essential. Rate limiting is a crucial defense mechanism for your Laravel applications, preventing malicious attacks, reducing server load, and ensuring fair resource allocation among users.

Table of Contents

Toggle
  • 1. Introduction: Why Laravel API Rate Limiting Matters
  • Table of Contents
  • 2. What Is API Rate Limiting?
  • 3. Common Rate Limiting Strategies
    • IP Address
    • API Key
    • Client ID
  • 4. Understanding Laravel Middleware
  • 5. Setting Up the Laravel API Project
    • Prerequisites
    • Cloning the Project
    • Installing Dependencies & Serving the App
  • 6. Remote Database Configuration in Hostinger
  • 7. Exploring Available API Routes
  • 8. Installing Laravel Throttle Package
  • 9. Rate Limiting Techniques in Laravel
    • 9.1 Blocking Specific IP Addresses
    • 9.2 Throttling by IP Address
    • 9.3 Throttling by User ID and Session
    • 9.4 Throttling Using Custom Headers (e.g., API Keys)
    • 9.5 Tiered Rate Limits for Guests vs. Authenticated Users
  • 10. Advanced Throttling with Laravel Throttle Package
    • attempt
    • hit
    • clear
    • count
    • check
  • 11. Customizing Throttle Responses
  • 12. Logging Rate Limit Violations
  • 13. Testing Rate Limiting Locally
  • 14. Deploying to Hostinger
  • 15. Post-Deployment: Handling Laravel Routes on Hostinger
  • 16. Final Testing With Postman and CURL
    • Testing with Postman
    • Testing with CURL
  • 17. Monitoring and Analytics for Rate Limiting
  • 18. Summary and Next Steps
    • Next Steps
    • Pay Writer
You Might Be Interested In
  • WordPress.com News: Exciting New Themes for July 2023
  • More Exciting WordPress.com Themes Added for July 2023 – Catch the Latest from WordPress.com
  • Step-by-Step Guide: Crafting an Ebook from Beginning to End [Includes Free Ebook Templates]
  • Understanding Website Traffic
  • Patterns for Business Websites on WordPress.com
  • How to improve Website Performance & Speed Up website

Without proper rate limiting, your API is vulnerable to:

  • Denial of Service (DoS) attacks
  • Brute force attempts on authentication endpoints
  • Excessive resource consumption by greedy clients
  • Increased infrastructure costs due to unnecessary traffic
  • Degraded performance for legitimate users

This comprehensive guide will walk you through implementing robust rate-limiting strategies in Laravel, from basic IP-based throttling to advanced custom solutions using the Laravel Throttle package. By the end, you’ll have the knowledge to deploy a secure, optimized API that can handle real-world traffic patterns while protecting against common threats.

Table of Contents

  • 1. Introduction: Why Laravel API Rate Limiting Matters
  • 2. What Is API Rate Limiting?
  • 3. Common Rate Limiting Strategies
    • IP Address
    • API Key
    • Client ID
  • 4. Understanding Laravel Middleware
  • 5. Setting Up the Laravel API Project
    • Prerequisites
    • Cloning the Project
    • Installing Dependencies & Serving the App
  • 6. Remote Database Configuration in Hostinger
  • 7. Exploring Available API Routes
  • 8. Installing Laravel Throttle Package
  • 9. Rate Limiting Techniques in Laravel
    • 9.1 Blocking Specific IP Addresses
    • 9.2 Throttling by IP Address
    • 9.3 Throttling by User ID and Session
    • 9.4 Throttling Using Custom Headers (e.g., API Keys)
    • 9.5 Tiered Rate Limits for Guests vs. Authenticated Users
  • 10. Advanced Throttling with Laravel Throttle Package
    • attempt
    • hit
    • clear
    • count
    • check
  • 11. Customizing Throttle Responses
  • 12. Logging Rate Limit Violations
  • 13. Testing Rate Limiting Locally
  • 14. Deploying to Hostinger
  • 15. Post-Deployment: Handling Laravel Routes on Hostinger
  • 16. Final Testing With Postman and CURL
    • Testing with Postman
    • Testing with CURL
  • 17. Monitoring and Analytics for Rate Limiting
  • 18. Summary and Next Steps
    • Next Steps

2. What Is API Rate Limiting?

Rate limiting is a strategy for controlling the amount of incoming and outgoing traffic to or from a network, API, or service. In the context of web applications, it restricts the number of requests a client can make to your API within a specific time frame.

For example, you might configure your API to allow:

  • 60 requests per minute per IP address
  • 1000 requests per day per API key
  • 5 login attempts per hour for a single user

When a client exceeds these limits, the server typically responds with a 429 “Too Many Requests” HTTP status code, often including headers that indicate when the client can resume making requests.

Rate limiting serves multiple purposes:

  • Security: Prevents brute force attacks and DDoS attempts
  • Resource management: Ensures fair distribution of server resources
  • Cost control: Limits API usage based on subscription tiers
  • Performance optimization: Prevents server overload during traffic spikes
Mastering Laravel API Rate Limiting to Secure Endpoints

3. Common Rate Limiting Strategies

IP Address

The most basic form of rate limiting tracks requests by the client’s IP address. This approach is simple to implement but has limitations:

Pros:

  • Easy to implement
  • Requires no client configuration
  • Works for all types of requests

Cons:

  • Multiple users behind a NAT or proxy may share the same IP
  • IP addresses can be spoofed
  • Mobile users may frequently change IPs

API Key

API keys provide a more reliable way to identify and throttle clients:

Pros:

  • More precise client identification
  • Can be revoked individually
  • Allows for different rate limits per client

Cons:

  • Requires key management infrastructure
  • Keys can be stolen if not properly secured
  • Additional overhead for authentication

Client ID

Using unique client identifiers can provide fine-grained control:

Pros:

  • Can be tied directly to user accounts
  • Enables tiered access levels
  • More difficult to circumvent than IP-based limits

Cons:

  • Requires user registration/authentication
  • More complex to implement
  • Increased database load for tracking

4. Understanding Laravel Middleware

Before diving into rate-limiting implementation, it’s important to understand Laravel’s middleware architecture. Middleware acts as a filtering mechanism for HTTP requests entering your application.

Laravel’s middleware provides a convenient layer where rate limiting logic can be applied:

namespace App\Http\Middleware;

use Closure;

class RateLimitMiddleware
{
    public function handle($request, Closure $next)
    {
        // Rate limiting logic goes here

        return $next($request);
    }
}

Laravel comes with built-in rate limiting middleware, but understanding how middleware works will help you implement custom solutions when needed.

Key middleware concepts for rate limiting:

  • Middleware can be applied globally, to route groups, or individual routes
  • Order matters when applying multiple middleware
  • Middleware can terminate early, preventing request processing
  • Response headers can be modified to provide rate limit information

5. Setting Up the Laravel API Project

Prerequisites

Before starting, ensure you have:

  • PHP 8.0 or higher
  • Composer
  • Git
  • A database system (MySQL, PostgreSQL, etc.)
  • Basic knowledge of Laravel

Cloning the Project

Let’s start by cloning a basic Laravel API project:

git clone https://github.com/yourusername/laravel-api-rate-limiting.git
cd laravel-api-rate-limiting

If you don’t have an existing project, create a new Laravel project:

composer create-project laravel/laravel laravel-api-rate-limiting
cd laravel-api-rate-limiting

Installing Dependencies & Serving the App

Install the required dependencies:

composer install
cp .env.example .env
php artisan key:generate

Configure your database connection in the .env file:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_api
DB_USERNAME=root
DB_PASSWORD=

Run migrations to set up your database:

php artisan migrate

Start the development server:

php artisan serve

6. Remote Database Configuration in Hostinger

If you’re using Hostinger as your hosting provider, configuring your database is straightforward:

  1. Log in to your Hostinger dashboard
  2. Navigate to Databases and click “Add Database”
  3. Select MySQL as the database type
  4. Choose your preferred region
  5. Name your database (e.g., laravel_api)
  6. Create a new user or select an existing one
  7. Note the connection details provided

Update your .env file with the Hostinger database credentials:

DB_CONNECTION=mysql
DB_HOST=your-Hostinger-db-host
DB_PORT=3306
DB_DATABASE=laravel_api
DB_USERNAME=your-username
DB_PASSWORD=your-password

To ensure secure connections, Hostinger requires SSL for database connections. Add the following to your config/database.php file:

'mysql' => [
    // other configuration...
    'sslmode' => env('DB_SSLMODE', 'require'),
    'options' => extension_loaded('pdo_mysql') ? array_filter([
        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
    ]) : [],
],

7. Exploring Available API Routes

Let’s create some example API routes that we’ll protect with rate limiting:

// routes/api.php

use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\ProductController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

// Public routes
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
Route::get('/products', [ProductController::class, 'index']);

// Protected routes
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
    Route::apiResource('/products/manage', ProductController::class)->except(['index']);
});

Create the necessary controllers:

php artisan make:controller API/AuthController
php artisan make:controller API/ProductController --resource

Implement basic controller logic for testing:

// App/Http/Controllers/API/AuthController.php
namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'user' => $user,
            'access_token' => $token,
            'token_type' => 'Bearer',
        ]);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        if (!Auth::attempt($request->only('email', 'password'))) {
            throw ValidationException::withMessages([
                'email' => ['The provided credentials are incorrect.'],
            ]);
        }

        $user = User::where('email', $request->email)->firstOrFail();
        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'user' => $user,
            'access_token' => $token,
            'token_type' => 'Bearer',
        ]);
    }
}

8. Installing Laravel Throttle Package

While Laravel includes built-in rate limiting capabilities, we’ll enhance our implementation with the laravel throttle package for more advanced features:

composer require graham-campbell/throttle

Publish the configuration file:

php artisan vendor:publish --provider="GrahamCampbell\Throttle\ThrottleServiceProvider"

This creates a config/throttle.php file that you can customize:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Cache Driver
    |--------------------------------------------------------------------------
    |
    | This defines the cache driver to be used. It may be the name of any
    | driver set in config/cache.php. Setting it to null will use the driver
    | you have set as default in config/cache.php.
    |
    | Default: null
    |
    */
    'driver' => null,
];

9. Rate Limiting Techniques in Laravel

9.1 Blocking Specific IP Addresses

Before implementing rate limiting, you might want to completely block certain IP addresses known for abuse:

Create a middleware to block specific IPs:

php artisan make:middleware BlockIpAddresses

Implement the middleware:

// app/Http/Middleware/BlockIpAddresses.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class BlockIpAddresses
{
    public $blockedIps = [
        '192.168.1.1',
        '10.0.0.5',
        // Add more IPs as needed
    ];

    public function handle(Request $request, Closure $next)
    {
        if (in_array($request->ip(), $this->blockedIps)) {
            abort(403, 'You are restricted to access the site.');
        }

        return $next($request);
    }
}

Register the middleware in app/Http/Kernel.php:

protected $routeMiddleware = [
    // Other middleware...
    'blockip' => \App\Http\Middleware\BlockIpAddresses::class,
];

Apply it to routes:

// routes/api.php
Route::middleware(['blockip'])->group(function () {
    // Your routes here
});

9.2 Throttling by IP Address

Laravel provides a built-in throttle middleware for IP-based rate limiting:

// routes/api.php
// Allow 60 requests per minute per IP
Route::middleware('throttle:60,1')->group(function () {
    Route::get('/products', [ProductController::class, 'index']);
});

For more granular control, create a custom middleware:

php artisan make:middleware IpThrottleMiddleware

Implement IP-based throttling:

// app/Http/Middleware/IpThrottleMiddleware.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class IpThrottleMiddleware
{
    protected $limiter;

    public function __construct(RateLimiter $limiter)
    {
        $this->limiter = $limiter;
    }

    public function handle(Request $request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        $key = 'ip:' . $request->ip();

        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            $seconds = $this->limiter->availableIn($key);

            return response()->json([
                'message' => 'Too many requests. Please try again later.',
                'retry_after' => $seconds,
            ], Response::HTTP_TOO_MANY_REQUESTS)
            ->header('Retry-After', $seconds);
        }

        $this->limiter->hit($key, $decayMinutes * 60);

        $response = $next($request);

        // Add rate limit headers to the response
        $response->headers->add([
            'X-RateLimit-Limit' => $maxAttempts,
            'X-RateLimit-Remaining' => $maxAttempts - $this->limiter->attempts($key) + 1,
        ]);

        return $response;
    }
}

Register and use the middleware:

// app/Http/Kernel.php
protected $routeMiddleware = [
    // Other middleware...
    'ip.throttle' => \App\Http\Middleware\IpThrottleMiddleware::class,
];

// routes/api.php
Route::middleware('ip.throttle:30,1')->group(function () {
    Route::get('/products', [ProductController::class, 'index']);
});

9.3 Throttling by User ID and Session

For authenticated routes, throttling by user ID provides more accurate control:

// routes/api.php
Route::middleware(['auth:sanctum', 'throttle:60,1'])->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
});

Create a custom middleware for user-based throttling:

php artisan make:middleware UserThrottleMiddleware

Implement the middleware:

// app/Http/Middleware/UserThrottleMiddleware.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class UserThrottleMiddleware
{
    protected $limiter;

    public function __construct(RateLimiter $limiter)
    {
        $this->limiter = $limiter;
    }

    public function handle(Request $request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        // Use user ID if authenticated, otherwise use IP
        $key = $request->user() 
            ? 'user:' . $request->user()->id 
            : 'ip:' . $request->ip();

        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            $seconds = $this->limiter->availableIn($key);

            return response()->json([
                'message' => 'Too many requests. Please try again later.',
                'retry_after' => $seconds,
            ], Response::HTTP_TOO_MANY_REQUESTS)
            ->header('Retry-After', $seconds);
        }

        $this->limiter->hit($key, $decayMinutes * 60);

        $response = $next($request);

        $response->headers->add([
            'X-RateLimit-Limit' => $maxAttempts,
            'X-RateLimit-Remaining' => $maxAttempts - $this->limiter->attempts($key) + 1,
        ]);

        return $response;
    }
}

Register and use the middleware:

// app/Http/Kernel.php
protected $routeMiddleware = [
    // Other middleware...
    'user.throttle' => \App\Http\Middleware\UserThrottleMiddleware::class,
];

// routes/api.php
Route::middleware('user.throttle:120,1')->group(function () {
    Route::post('/login', [AuthController::class, 'login']);
    Route::post('/register', [AuthController::class, 'register']);
});

9.4 Throttling Using Custom Headers (e.g., API Keys)

For API-key based throttling, create a middleware that looks for an API key in the request headers:

php artisan make:middleware ApiKeyThrottleMiddleware

Implement the middleware:

// app/Http/Middleware/ApiKeyThrottleMiddleware.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class ApiKeyThrottleMiddleware
{
    protected $limiter;

    public function __construct(RateLimiter $limiter)
    {
        $this->limiter = $limiter;
    }

    public function handle(Request $request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        // Get API key from header or fallback to IP
        $apiKey = $request->header('X-API-KEY');
        $key = $apiKey ? 'api:' . $apiKey : 'ip:' . $request->ip();

        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            $seconds = $this->limiter->availableIn($key);

            return response()->json([
                'message' => 'API rate limit exceeded. Please try again later.',
                'retry_after' => $seconds,
            ], Response::HTTP_TOO_MANY_REQUESTS)
            ->header('Retry-After', $seconds);
        }

        $this->limiter->hit($key, $decayMinutes * 60);

        $response = $next($request);

        $response->headers->add([
            'X-RateLimit-Limit' => $maxAttempts,
            'X-RateLimit-Remaining' => $maxAttempts - $this->limiter->attempts($key) + 1,
        ]);

        return $response;
    }
}

Register and use the middleware:

// app/Http/Kernel.php
protected $routeMiddleware = [
    // Other middleware...
    'apikey.throttle' => \App\Http\Middleware\ApiKeyThrottleMiddleware::class,
];

// routes/api.php
Route::middleware('apikey.throttle:100,1')->group(function () {
    Route::get('/products', [ProductController::class, 'index']);
});

9.5 Tiered Rate Limits for Guests vs. Authenticated Users

Different user types often deserve different rate limits. Let’s implement a tiered approach:

php artisan make:middleware TieredRateLimitMiddleware

Implement the middleware:

// app/Http/Middleware/TieredRateLimitMiddleware.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class TieredRateLimitMiddleware
{
    protected $limiter;

    public function __construct(RateLimiter $limiter)
    {
        $this->limiter = $limiter;
    }

    public function handle(Request $request, Closure $next)
    {
        // Define different limits based on authentication status
        if ($request->user()) {
            // Authenticated user - higher limits
            $maxAttempts = 120;
            $decayMinutes = 1;
            $key = 'user:' . $request->user()->id;

            // Premium users can get even higher limits
            if ($request->user()->isPremium()) {
                $maxAttempts = 300;
            }
        } else {
            // Guest user - lower limits
            $maxAttempts = 30;
            $decayMinutes = 1;
            $key = 'ip:' . $request->ip();
        }

        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            $seconds = $this->limiter->availableIn($key);

            return response()->json([
                'message' => 'Rate limit exceeded. Please try again later.',
                'retry_after' => $seconds,
            ], Response::HTTP_TOO_MANY_REQUESTS)
            ->header('Retry-After', $seconds);
        }

        $this->limiter->hit($key, $decayMinutes * 60);

        $response = $next($request);

        $response->headers->add([
            'X-RateLimit-Limit' => $maxAttempts,
            'X-RateLimit-Remaining' => $maxAttempts - $this->limiter->attempts($key) + 1,
        ]);

        return $response;
    }
}

Add the isPremium method to the User model:

// app/Models/User.php
public function isPremium()
{
    // Logic to determine if user has premium status
    return $this->subscription_type === 'premium';
}

Register and use the middleware:

// app/Http/Kernel.php
protected $routeMiddleware = [
    // Other middleware...
    'tiered.throttle' => \App\Http\Middleware\TieredRateLimitMiddleware::class,
];

// routes/api.php
Route::middleware('tiered.throttle')->group(function () {
    Route::get('/products', [ProductController::class, 'index']);
    // Other routes that should have tiered rate limiting
});

10. Advanced Throttling with Laravel Throttle Package

The Laravel Throttle package provides more advanced features for rate limiting. Let’s explore how to use its key methods:

First, inject the throttle manager into your controller:

// app/Http/Controllers/API/AdvancedThrottleController.php
namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use GrahamCampbell\Throttle\Facades\Throttle;
use Illuminate\Http\Request;

class AdvancedThrottleController extends Controller
{
    public function throttledEndpoint(Request $request)
    {
        // Implementation will go here
    }
}

attempt

The attempt method checks if an action can be performed and increments the counter if allowed:

public function throttledEndpoint(Request $request)
{
    $key = $request->user() ? $request->user()->id : $request->ip();

    // Allow 5 attempts per minute
    $limit = 5;
    $time = 60;

    if (Throttle::attempt(['key' => $key, 'limit' => $limit, 'time' => $time])) {
        // Action is allowed
        return response()->json(['message' => 'Request processed successfully']);
    } else {
        // Too many attempts
        return response()->json(['message' => 'Too many attempts, please try again later'], 429);
    }
}

hit

The hit method increments the counter without checking the limit:

public function incrementCounter(Request $request)
{
    $key = $request->ip();

    // Increment the counter with 60 seconds expiry
    Throttle::hit(['key' => $key, 'time' => 60]);

    return response()->json(['message' => 'Counter incremented']);
}

clear

The clear method resets the counter:

public function resetCounter(Request $request)
{
    $key = $request->ip();

    Throttle::clear(['key' => $key]);

    return response()->json(['message' => 'Counter reset successfully']);
}

count

The count method returns the current counter value:

public function getCounter(Request $request)
{
    $key = $request->ip();

    $count = Throttle::count(['key' => $key]);

    return response()->json(['counter' => $count]);
}

check

The check method verifies if an action is allowed without incrementing the counter:

public function checkLimit(Request $request)
{
    $key = $request->ip();
    $limit = 5;
    $time = 60;

    $allowed = Throttle::check(['key' => $key, 'limit' => $limit, 'time' => $time]);

    return response()->json([
        'allowed' => $allowed,
        'remaining_attempts' => $allowed ? ($limit - Throttle::count(['key' => $key])) : 0
    ]);
}

Create a route for the advanced throttle controller:

// routes/api.php
Route::get('/advanced-throttle', [AdvancedThrottleController::class, 'throttledEndpoint']);
Route::get('/advanced-throttle/count', [AdvancedThrottleController::class, 'getCounter']);
Route::get('/advanced-throttle/check', [AdvancedThrottleController::class, 'checkLimit']);
Route::post('/advanced-throttle/reset', [AdvancedThrottleController::class, 'resetCounter']);

11. Customizing Throttle Responses

Customize how your API responds when rate limits are exceeded by creating a custom exception handler:

// app/Exceptions/Handler.php
namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Throwable;

class Handler extends ExceptionHandler
{
    // Other methods...

    public function render($request, Throwable $exception)
    {
        if ($exception instanceof ThrottleRequestsException) {
            return response()->json([
                'error' => 'Rate limit exceeded',
                'message' => 'You have made too many requests. Please wait before trying again.',
                'retry_after' => $exception->getHeaders()['Retry-After'],
                'docs_url' => 'https://api.example.com/docs/rate-limits',
            ], 429);
        }

        return parent::render($request, $exception);
    }
}

12. Logging Rate Limit Violations

Track rate limit violations to identify potential abuse patterns:

Create a custom middleware for logging:

php artisan make:middleware LogRateLimitMiddleware

Implement the middleware:

// app/Http/Middleware/LogRateLimitMiddleware.php
namespace App\Http\Middleware;

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

class LogRateLimitMiddleware
{
    protected $limiter;

    public function __construct(RateLimiter $limiter)
    {
        $this->limiter = $limiter;
    }

    public function handle(Request $request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        $key = $request->user() ? 'user:' . $request->user()->id : 'ip:' . $request->ip();

        // Check if this request will exceed the limit
        if ($this->limiter->attempts($key) >= $maxAttempts - 1) {
            // Log the violation
            Log::warning('Rate limit exceeded', [
                'key' => $key,
                'ip' => $request->ip(),
                'user_agent' => $request->userAgent(),
                'path' => $request->path(),
                'attempts' => $this->limiter->attempts($key),
                'max_attempts' => $maxAttempts,
            ]);

            // You could also notify admins or trigger alerts here
        }

        return $next($request);
    }
}

Register and use the middleware:

// app/Http/Kernel.php
protected $routeMiddleware = [
    // Other middleware...
    'log.ratelimit' => \App\Http\Middleware\LogRateLimitMiddleware::class,
];

// routes/api.php
Route::middleware(['throttle:5,1', 'log.ratelimit:5,1'])->group(function () {
    Route::post('/login', [AuthController::class, 'login']);
});

13. Testing Rate Limiting Locally

To test your rate limiting implementation, create a simple test script:

php artisan make:test RateLimitingTest

Implement the test:

// tests/Feature/RateLimitingTest.php
namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RateLimitingTest extends TestCase
{
    use RefreshDatabase;

    public function test_basic_rate_limiting()
    {
        // Make multiple requests to a rate-limited endpoint
        for ($i = 0; $i < 5; $i++) {
            $response = $this->get('/api/products');
            $response->assertStatus(200);
        }

        // The 6th request should be rate limited
        $response = $this->get('/api/products');
        $response->assertStatus(429);

        // Verify the response contains the correct headers
        $this->assertTrue($response->headers->has('Retry-After'));
    }

    public function test_user_based_rate_limiting()
    {
        // Create and authenticate a user
        $user = \App\Models\User::factory()->create();
        $this->actingAs($user);

        // Make requests up to the limit
        for ($i = 0; $i < 60; $i++) {
            $response = $this->get('/api/user');
            $response->assertStatus(200);
        }

        // The next request should be rate limited
        $response = $this->get('/api/user');
        $response->assertStatus(429);
    }
}

Run the tests:

php artisan test --filter=RateLimitingTest

14. Deploying to Hostinger

To deploy your Laravel API with rate limiting to Hostinger:

  1. Push your code to a Git repository (GitHub, GitLab, Bitbucket)
  2. Log in to your Hostinger dashboard
  3. Create a new application
  4. Select “Laravel” as your application type
  5. Connect your Git repository
  6. Configure deployment settings:
  • PHP version: 8.1+
  • Environment variables (copy from your .env file)
  • Database connection details
  1. Add the following to your Procfile:
web: vendor/bin/heroku-php-apache2 public/
  1. Configure environment variables in the Hostinger dashboard:
APP_ENV=production
APP_DEBUG=false
APP_KEY=your-app-key
DB_CONNECTION=mysql
DB_HOST=your-Hostinger-db-host
DB_PORT=3306
DB_DATABASE=your-db-name
DB_USERNAME=your-username
DB_PASSWORD=your-password
  1. Deploy your application

15. Post-Deployment: Handling Laravel Routes on Hostinger

After deployment, ensure your Laravel routes are properly handled:

Create a custom Nginx configuration for your Hostinger application:

# Hostinger-nginx-config.conf
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

Add the configuration to Hostinger through the Hostinger dashboard:

  • Navigate to your site
  • Go to “Tools & Settings” > “Nginx Configuration”
  • Paste the above configuration
  • Save changes

16. Final Testing With Postman and CURL

Testing with Postman

  1. Create a new Postman collection for your API
  2. Add requests for your endpoints
  3. Use the “Runner” feature to send multiple requests in succession
  4. Verify that rate limiting is working by checking for 429 responses
  5. Examine the response headers for rate limit information

Example test script for Postman:

// Test rate limit headers
pm.test("Rate limit headers are present", function() {
    pm.response.to.have.header("X-RateLimit-Limit");
    pm.response.to.have.header("X-RateLimit-Remaining");
});

// If rate limited, verify 429 status
if (pm.response.code === 429) {
    pm.test("Rate limited response has Retry-After header", function() {
        pm.response.to.have.header("Retry-After");
    });
}

Testing with CURL

Test your API endpoints with CURL commands:

# Make multiple requests to test rate limiting
for i in {1..10}; do
  curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://your-api.hostinger.app/api/products
  echo "\n--- Request $i complete ---\n"
  sleep 1
done

Check for the rate limit headers in the response:

curl -i -H "Accept: application/json" http://your-api.hostinger.app/api/products

17. Monitoring and Analytics for Rate Limiting

Understanding how your rate limits affect users is crucial. Let’s add a section on monitoring:

// app/Http/Middleware/RateLimitAnalyticsMiddleware.php
namespace App\Http\Middleware;

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

class RateLimitAnalyticsMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        // Only track API requests
        if (strpos($request->path(), 'api/') === 0) {
            // Store analytics data
            DB::table('rate_limit_analytics')->insert([
                'path' => $request->path(),
                'method' => $request->method(),
                'status_code' => $response->status(),
                'ip' => $request->ip(),
                'user_id' => $request->user() ? $request->user()->id : null,
                'user_agent' => $request->userAgent(),
                'rate_limited' => $response->status() === 429,
                'created_at' => now(),
            ]);
        }

        return $response;
    }
}

Create the migration for the analytics table:

php artisan make:migration create_rate_limit_analytics_table

Define the migration:

// database/migrations/xxxx_xx_xx_create_rate_limit_analytics_table.php
public function up()
{
    Schema::create('rate_limit_analytics', function (Blueprint $table) {
        $table->id();
        $table->string('path');
        $table->string('method', 10);
        $table->integer('status_code');
        $table->string('ip');
        $table->unsignedBigInteger('user_id')->nullable();
        $table->string('user_agent')->nullable();
        $table->boolean('rate_limited');
        $table->timestamp('created_at');
    });
}

Register the middleware in app/Http/Kernel.php:

protected $middleware = [
    // Other middleware...
    \App\Http\Middleware\RateLimitAnalyticsMiddleware::class,
];

Create a dashboard to visualize the data:

// app/Http/Controllers/RateLimitDashboardController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class RateLimitDashboardController extends Controller
{
    public function index()
    {
        $stats = [
            'total_requests' => DB::table('rate_limit_analytics')->count(),
            'rate_limited_requests' => DB::table('rate_limit_analytics')->where('rate_limited', true)->count(),
            'top_rate_limited_paths' => DB::table('rate_limit_analytics')
                ->where('rate_limited', true)
                ->select('path', DB::raw('count(*) as count'))
                ->groupBy('path')
                ->orderBy('count', 'desc')
                ->limit(5)
                ->get(),
            'top_rate_limited_ips' => DB::table('rate_limit_analytics')
                ->where('rate_limited', true)
                ->select('ip', DB::raw('count(*) as count'))
                ->groupBy('ip')
                ->orderBy('count', 'desc')
                ->limit(5)
                ->get(),
        ];

        return view('rate-limit-dashboard', ['stats' => $stats]);
    }
}

18. Summary and Next Steps

In this comprehensive guide, we’ve explored various techniques for implementing rate limiting in Laravel APIs:

  1. Basic rate limiting using Laravel’s built-in middleware
  2. IP-based throttling for public endpoints
  3. User-based throttling for authenticated requests
  4. API key throttling for third-party integrations
  5. Tiered rate limiting for different user types
  6. Advanced throttling with the Laravel Throttle package
  7. Custom response handling for rate limit violations
  8. Logging and monitoring rate limit events
  9. Testing rate limiting implementation
  10. Deployment to Hostinger and post-deployment configuration

Next Steps

To further enhance your API’s rate limiting:

  1. Implement dynamic rate limits that adjust based on server load
  2. Add caching to reduce database load from frequent limit checks
  3. Set up alerts for unusual rate limit violations that might indicate attacks
  4. Create a rate limit status endpoint for clients to check their current limits
  5. Document your rate limits clearly in your API documentation
  6. Consider using Redis for distributed rate limiting in multi-server setups

By implementing these rate limiting strategies, you’ve taken a significant step toward building a more secure, stable, and fair API for all users. Rate limiting not only protects your infrastructure but also ensures that your services remain available and responsive even under heavy load or during attempted abuse.

Remember that rate limiting is just one aspect of API security. Continue to improve your authentication, authorization, input validation, and other security measures to build a truly robust API ecosystem.

Pay Writer

Buy author a coffee

Pay Writer
0 comments 0 FacebookTwitterPinterestEmail
developershohel

previous post
Adding a Dynamic Copyright Date to your WordPress Footer: A Step-by-Step Tutorial
next post
Top 10 Best WordPress Backup Plugins in 2024

Related Posts

How to improve Website Performance & Speed Up...

February 20, 2024

10 Best WordPress Image Optimization Plugins in 2024

February 20, 2024

Top 5 hosting to WordPress Staging Site with...

December 29, 2023

Writing a Blog Post Using AI in WordPress...

August 20, 2023

10 Useful Ways to Utilize AI in WordPress

August 19, 2023

Ultimate Guide on How to Add 2FA Authentication...

August 18, 2023

Comparison of the Top 6 Best WooCommerce Shipping...

August 18, 2023

Top 7 Link Tracking URL Shorteners for WordPress

August 18, 2023

2 Simple Methods to Highlight Text in WordPress

August 18, 2023

Comparison of the Top 5 Managed MySQL Hosting...

August 17, 2023

Leave a Comment Cancel Reply

Save my name, email, and website in this browser for the next time I comment.

* By using this form you agree with the storage and handling of your data by this website.

Weather

New York
overcast clouds
55%
4.1km/h
100%
1°C
2°
-0°
-1°
Wed

Recent Posts

  • How to improve Website Performance & Speed Up website

    February 20, 2024
  • 10 Best WordPress Image Optimization Plugins in 2024

    February 20, 2024
  • Top 10 Best WordPress Themes for Woocommerce in 2024

    January 1, 2024
  • How to use ftp or sftp server to transfer files in 2024

    December 30, 2023
  • Upload WordPress From localhost to live server in 2024

    December 30, 2023

STAY TUNED WITH US

Sign up for our newsletter to receive our latest blogs.

Get Best Web Hosting and Services for your Business

Hostinger

Hostinger

Bluehost

Bluehost

WP Engine

Name.com

Name.com

Resources

  • Developer Shohel
  • Url Shortener
  • All in One Online tools
  • Secure Cloud Storage
  • Books
  • Fashion Product
  • IT Blogger

Company

  • Privacy Policy
  • Refund Policy
  • Terms and Conditions
  • Cookie Policy
  • Contact us
  • About us

Most read

How to improve Website Performance & Speed Up website
February 20, 2024
10 Best WordPress Image Optimization Plugins in 2024
February 20, 2024
Top 10 Best WordPress Themes for Woocommerce in 2024
January 1, 2024
Codepen Blog | Top blogs for WordPress and Web Development
Facebook-f Twitter Instagram Linkedin Behance Github

@2024 – All Right Reserved. Designed and Developed by Developer Shohel

Codepen Blog
  • Home
  • About us
  • Contact us
Codepen Blog
  • Home
  • About us
  • Contact us
@2021 - All Right Reserved. Designed and Developed by PenciDesign

Read alsox

An Effortless WordPress Affiliate Plugin for All...

July 27, 2023

Creating a Net Promoter Score® (NPS) Survey...

August 15, 2023

Creating Drop-Down Menus in Excel: A Comprehensive...

August 9, 2023
Sign In

Keep me signed in until I sign out

Forgot your password?

Do not have an account ? Register here

Password Recovery

A new password will be emailed to you.

Have received a new password? Login here

Register New Account

Have an account? Login here

Shopping Cart

Close

No products in the cart.

Return To Shop
Close