Rate limit Logo

Introduction

How to configure

Ensure the kernel file is loading the throttle middleware

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array<int, class-string|string>
     */
    protected $middleware = [
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\CheckAllowedVisibilityMaintenance::class,
        \App\Http\Middleware\AccessLogRequests::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            
            
            
            \Illuminate\Routing\Middleware\ThrottleRequests::class, <------------- Ensure this!
            
            
            
        ],
        'api' => [
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
}

API routes file

( The comments in the file explain the expected behavior )

<?php

use App\Http\Controllers\AdminController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\MessagesController;
use App\Http\Controllers\HomeController;
use Illuminate\Support\Facades\Route;

// Rate limit on ( 5 post requests per 5 min )
Route::middleware('throttle:5,5')->group(function () {
    Route::post('/send',
        [
            MessagesController::class, 'send'
        ]
    )->name('send');
});

Route::prefix('v1')->group(function () {

    // Allow 10 tries to log in per min
    Route::middleware('throttle:10,1')->group(function () {
        Route::post('/login',
            [
                AuthController::class, 'login'
            ]
        )->name('login');
    });

    // Protected routes by Sanctum
    Route::middleware('auth:sanctum')->group(function ()
    {
        // Allow a margin of 3 logouts per min as it should run once a time
        Route::middleware('throttle:3,1')->group(function () {
            Route::post('/logout',
                [
                    AuthController::class, 'logout'
                ]
            )->name('logout');
        });

        // Allow a margin of 5 refresh per min, as it only suppose to run rarely
        Route::middleware('throttle:5,1')->group(function () {
            Route::post('/refresh',
                [
                    AuthController::class, 'refresh'
                ]
            )->name('refresh');
        });

        // Allow 5 refresh per min, as it will be cached
        Route::middleware('throttle:5,1')->group(function () {
            Route::post('/user',
                [
                    AuthController::class, 'user'
                ]
            )->name('user');
        });

        // Check if user is authenticated...
        // This route will be cached as well... No need more than 1 non cached access per minute
        Route::get('/check',
            [
                AuthController::class, 'check'
            ]
        )->name('check');

        // Private home page. Let's allow 30 accesses per min
        Route::middleware('throttle:30,1')->group(function () {
            Route::get('/home',
                [
                    HomeController::class, 'index'
                ]
            )->name('home.index');
        });
    });
});

How it works

User identification:

Access control:

Limit expiration:

Demonstration

( Click on the image to watch the video )

Demonstration video