Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lara28580's avatar

Rate limiting on different methods

I wanna limit the request to two different methods in two different controllers I set it up like that.

Controller 1

/**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('throttle:5,1')->only('store');
    }

Controller 2

/**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('throttle:2,10')->only('store');
    }

So now if the first middleware in the first controller takes effect I cant use the second one either. I thought the route throttles are indepentend from each other?

0 likes
6 replies
D9705996's avatar

@SmokeTM - rate limiting is by user rather than route j think

https://laravel.com/docs/5.7/routing#rate-limiting

Looking at the framework code the rate limiting cache key is generated based on this function

protected function resolveRequestSignature($request)
    {
        if ($user = $request->user()) {
            return sha1($user->getAuthIdentifier());
        }
        if ($route = $request->route()) {
            return sha1($route->getDomain().'|'.$request->ip());
        }
        throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
    }

This explains your 429 as both routes will return return sha1($user->getAuthIdentifier());

lara28580's avatar

Ok thanks for that!! You know a way to prevent spam on methods? Lets say you dont want a user to post 20 comments in a minute or something like that? Is there a common way to do it with laravel or I have to create something on my own?

Best

D9705996's avatar

Looking back at the logic in the function I posted it does look like the route and ip are used if your using a stateless api. Therefore it depends on whether you have an authenticated user or not.

If you need per route limiting for you web routes you are going to need to write your own middleware. Not tested but this might work

<?php 

namespace App\Http\Middleware;

use RuntimeException;
use Illuminate\Routing\Middleware\ThrottleRequests;

class ThrottleRequestsByRoute extends ThrottleRequests

    protected function resolveRequestSignature($request)
    {
        if ($route = $request->route()) {
            return sha1($route->getDomain().'|'.$request->ip());
        }
        throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
    }
}

You can then add to your routes. Not 100% on this working but worth a try. It might also mess with the existing middleware so YMMV

lara28580's avatar

Thanks for you code implemented it but how to limit the route requests now? How to achieve that it works like the throttle middleware $this->middleware('routeThrottle:2,10')->only('store');?

D9705996's avatar
D9705996
Best Answer
Level 51

You need to register the middleware in app/Http/Kernel.php

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'routeThrottle' => \Illuminate\Routing\Middleware\ThrottleRequestsByRoute::class, // add this
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];

Then your $this->middleware('routeThrottle:2,10')->only('store'); should work

1 like
lara28580's avatar

Registered it already in the kernel.php but did not know that it works already like $this->middleware('routeThrottle:2,10')->only('store'); that. Thanks !

1 like

Please or to participate in this conversation.