Skip to content

UseMuffin/Throttle

Repository files navigation

Throttle

Build Status Coverage Status Total Downloads License

(API) Rate limiting requests in CakePHP

This plugin allows you to limit the number of requests a client can make to your app in a given time frame.

Requirements

  • CakePHP cache engine with support for atomic updates

Installation

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 src/Application.php:

$this->addPlugin('Muffin/Throttle');

Configuration

In your config/app.php add a cache config named throttle under the Cache key with required config. For e.g.:

'throttle' => [
    'className' => 'Apcu',
    'prefix' => 'throttle_'
],

Note: This plugin will NOT work when using the File cache engine as it does not support atomic increment.

Using the Middleware

Include the middleware in inside of the Application.php:

use Muffin\Throttle\Middleware\ThrottleMiddleware;
use Psr\Http\Message\ServerRequestInterface;

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([
        'response' => [
            'body' => 'Rate limit exceeded',
        ],
        'interval' => '+1 hour',
        'limit' => 300,
        'identifier' => function (ServerRequestInterface $request) {
            if (!empty($request->getHeaderLine('Authorization'))) {
                return str_replace('Bearer ', '', $request->getHeaderLine('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.

X-headers

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.

Customize response object

You may use type and headers subkeys of the response array (as you would do with a Response object) if you want to return a different message as the default one:

new ThrottleMiddleware([
    'response' => [
        'body' => json_encode(['error' => 'Rate limit exceeded']),
        'type' => 'json',
        'headers' => [
            'Custom-Header' => 'custom_value',
        ]
    ],
    'limit' => 300,
]);

Patches & Features

  • 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.

Bugs & Feedback

http://github.com/usemuffin/throttle/issues

License

Copyright (c) 2015-Present, [Use Muffin] and licensed under The MIT License.