PSR-15 middleware for rate limiting requests per client IP address (or per user id) using a fixed-window counter backed by a PSR-6 cache pool.
It is framework agnostic and works with any PSR-15 stack (Slim 4, Mezzio, Laminas, ...).
composer require antoninom90/php-rate-limiter-middlewareuse Antoninom90\RateLimiter\RateLimitMiddleware;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Http\Message\ResponseFactoryInterface;
$app->add(new RateLimitMiddleware(
$container->get(CacheItemPoolInterface::class), // any PSR-6 pool
$container->get(ResponseFactoryInterface::class),
60, // limit: maximum requests per window
60 // window: window size in seconds
));- every request counts against the current fixed window;
- the requestor key is the client IP address (
REMOTE_ADDR, or theip_addressrequest attribute when set by an outer middleware); - if the request carries a user id (the
user_idrequest attribute or theuser_idsession key), the limit applies to that user instead of the IP; - allowed responses carry
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Resetheaders; - once the limit is reached the client receives a
429 Too Many RequestsJSON response with aRetry-Afterheader; - counters expire at the end of each window.
use Antoninom90\RateLimiter\RateLimitMiddleware;
use Psr\Cache\CacheItemPoolInterface;
use Slim\App;
use Slim\Psr7\Factory\ResponseFactory;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cachePool = new FilesystemAdapter('rate_limit', 0, __DIR__ . '/var/cache/rate_limit');
$app = AppFactory::create();
$app->add(new RateLimitMiddleware(
$cachePool,
new ResponseFactory(),
60,
60
));- PHP ^8.1
psr/cache^3.0,psr/http-factory^1.0,psr/http-message^1.1|^2.0,psr/http-server-middleware^1.0
The MIT License (MIT). Please see LICENSE for more information.