Reputation: 1533
How to override group middleware? What i want to achieve is to add other throttle limit for register/login routes.
My current throttle is set in kernel.
'api' => [
'throttle:40,1',
'bindings',
],
I want to set new throttle limit for login/register routes.
This is how i did it.
Route::post('login', 'Api\UserController@login')->middleware('throttle:15,3')->name('user.login');
Route::post('register', 'Api\UserController@register')->middleware('throttle:15,3')->name('user.register');
When i run php artisan route:list it says that this middleware api,throttle:15,3 is applied to this route.
The problem is when i run login request, response header says
X-RateLimit-Limit 40
X-RateLimit-Remaining 38
So as far as i see my new middleware is not applied. But my throttle requests are counted twice. How can i apply different middleware for throttle on login/register routes and override the old one ?
Upvotes: 10
Views: 4686
Reputation: 763
Remove the Throttle Middleware from the Global Group: In your app/Http/Kernel.php file, remove the Throttle Middleware from the global api group. The global group is applied to all routes by default.
Change this:
'api' => [
'throttle:40,1',
'bindings',
],
to this:
'api' => [
'bindings',
],
Define a New Middleware Group: Create a new middleware group in your app/Http/Kernel.php file specifically for API throttling. You can give it a custom name like 'api.throttle'.
'api.throttle' => [
'throttle:40,1', // The default throttle for most API routes
],
Apply the Custom Middleware Group to Most API Routes: Now, apply your new api.throttle middleware group to most of your API routes in your routes/api.php file. This will apply the default throttle to most routes.
Route::middleware(['api.throttle'])->group(function () {
// Define your API routes here.
});
Override the Middleware on Login/Register Routes: For the login and register routes, you can override the api.throttle middleware with your custom throttle settings.
Route::post('login', 'Api\UserController@login')->middleware('throttle:15,3')->name('user.login');
Route::post('register', 'Api\UserController@register')->middleware('throttle:15,3')->name('user.register');
This is just an idea and the approach which I use most.
OR You can create a new call like below.
Define a new middleware group in the App\Http\Kernel.php file. For example, let's call it throttle-auth:
'throttle-auth' => 'throttle:15,3',
Apply like below.
Route::group(['middleware' => 'throttle-auth'], function () {
Route::post('login', 'Api\UserController@login')->name('user.login');
Route::post('register', 'Api\UserController@register')->name('user.register');
});
Upvotes: 0
Reputation: 424
As far as I know, the only way to override a group middleware is to disable it and then enable another one:
Route::withoutMiddleware(ThrottleRequests::class.':api')->group(function () {
Route::middleware(ThrottleRequests::class.':custom')->group(function () {
///
});
});
Let me know if there's a better way to do it. I'd like to clean this up.
Upvotes: 1
Reputation: 1804
Old topic, but its the first i found; time for an updated answer.
I've had this problem in the past as well. My solution back then was to add the middleware in the constructor of the controllers. I dislike it but it works.
I'm currently using Laravel 8 with a new project and found that the following solution works:
kernel.php
'api' => [
'throttle:40,1',
'bindings',
],
throttle:40,1
from the specific route, and add the correct middleware throttle:15,3
:Route::post('login', 'Api\UserController@login')->withoutMiddleware('throttle:40,1')->middleware('throttle:15,3')->name('user.login');
If you do not remove the middleware, it will run the throttle middleware twice per request.
I also played around with $this->middleware( 'throttle:40,1' )->except( ['login'] )
in the constructor of Api\UserController
, however that does not give the required result; it will just add the middleware for all but one method, it does not overwrite.
Upvotes: 8
Reputation: 559
Had this same question and just did some research. It doesn't appear that there is a way to overwrite the middleware configuration.
I, too, see that my middleware has updated in route:list
but when resolving the middleware, it always uses a merged set of rules and so that initial api
rule will end up overriding anything that defines something else over that.
You have a couple of options:
Remove the throttle rule from the Kernel api
middleware definition and then use a Route::group()
to re-add that specific rule to the rest of the routes. Then, in the same file, you can create a new Route::group()
which defines the custom throttle config.
Route::group(['middleware' => 'throttle:120,1'], function () {
...
});
Route::group(['middleware' => 'throttle:15,3'], function () {
...
});
Create a custom api-auth.php
file which is wrapped in a custom middleware group that you define just like the default api
middleware. (You'll need to add another call in your RouteServiceProvider
to load it like this:
public function map() {
...
$this->mapCustomAuthRoutes();
}
protected function mapCustomAuthRoutes()
{
Route::middleware(['throttle:15,3', 'bindings'])
->namespace($this->namespace)
->as('api.')
->group(base_path('routes/api-auth.php'));
}
Upvotes: 1