(API) Rate limiting requests in CakePHP 3
This plugin allows you to limit the number of requests a client can make to your app in a given time frame.
- CakePHP 3.0+
- CakePHP cache engine with support for atomic updates
composer require muffin/throttle
To make your application load the plugin either run:
./bin/cake plugin load Muffin/Throttle
or add the following line to config/bootstrap.php
:
Plugin::load('Muffin/Throttle');
In your config/app.php
add a cache config named throttle
under the Cache
key
with required config. For e.g.:
'throttle' => [
'className' => 'Apc',
'prefix' => 'throttle_'
],
Note: This plugin will NOT work when using the File
cache engine as it
does not support atomic increment.
Note: This requires Cakephp version 3.4 or greater.
Include the middleware in inside of the Application.php:
use Muffin\Throttle\Middlware\ThrottleMiddleware;
Add the middleware to the stack and pass your custom configuration:
public function middleware($middleware)
{
// Various other middlewares for error handling, routing etc. added here.
$throttleMiddleware = new ThrottleMiddleware([
'message' => 'Rate limit exceeded',
'interval' => '+1 hour',
'limit' => 300,
'identifier' => function (ServerRequestInterface $request) {
if (null !== $request->header('Authorization')) {
return str_replace('Bearer ', '', $request->header('Authorization'));
}
return $request->clientIp();
}
]);
$middlewareQueue->add($throttleMiddleware);
return $middlewareQueue;
}
The above example would allow 300 requests/hour/token and would first try to identify the client by JWT Bearer token before falling back to (Throttle default) IP address based identification.
By default Throttle will add X-headers with rate limiting information to all responses:
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1438434161
To customize the header names simply pass (all of them) under headers
key in
your configuration array:
'headers' => [
'limit' => 'X-MyRateLimit-Limit',
'remaining' => 'X-MyRateLimit-Remaining',
'reset' => 'X-MyRateLimit-Reset'
]
To disable the headers set headers
key to false
.
In bootstrap.php
:
Include the class namespace:
use Cake\Routing\DispatcherFactory;
Add a configuration:
DispatcherFactory::add('Muffin/Throttle.Throttle');
This will use the defaults, 10 requests per minute for any given IP. You could easily change that by passing your own configuration:
DispatcherFactory::add('Muffin/Throttle.Throttle', [
'message' => 'Rate limit exceeded',
'interval' => '+1 hour',
'limit' => 300,
'identifier' => function (Request $request) {
if (null !== $request->header('Authorization')) {
return str_replace('Bearer ', '', $request->header('Authorization'));
}
return $request->clientIp();
}
]);
- Fork
- Mod, fix
- Test - this is important, so it's not unintentionally broken
- Commit - do not mess with license, todo, version, etc. (if you do change any, bump them into commits of their own that I can ignore when I pull)
- Pull request - bonus point for topic branches
To ensure your PRs are considered for upstream, you MUST follow the CakePHP coding standards.
http://github.com/usemuffin/throttle/issues
Copyright (c) 2015-2017, [Use Muffin] and licensed under The MIT License.