Express Slow Down
Basic rate-limiting middleware for Express that slows down responses rather than blocking them outright. Use to limit repeated requests to public APIs and/or endpoints such as password reset.
Plays nice with Express Rate Limit
Note: this module does not share state with other processes/servers by default. This module was extracted from Express Rate Limit 2.x and can work with it's stores:
Stores
- Memory Store (default, built-in) - stores hits in-memory in the Node.js process. Does not share state with other servers or processes.
- Redis Store
- Memcached Store
Note: when using express-slow-down and express-rate-limit with an external store, you'll need to create two instances of the store and provide different prefixes so that they don't double-count requests.
Install
$ npm install --save express-slow-down
Usage
For an API-only server where the rules should be applied to all requests:
const slowDown = require("express-slow-down");
app.enable("trust proxy");
const speedLimiter = slowDown({
windowMs: 15 * 60 * 1000,
delayAfter: 100,
delayMs: 500
});
app.use(speedLimiter);
For a "regular" web server (e.g. anything that uses express.static()
), where the rate-limiter should only apply to certain requests:
const slowDown = require("express-slow-down");
app.enable("trust proxy");
const resetPasswordSpeedLimiter = slowDown({
windowMs: 15 * 60 * 1000,
delayAfter: 5,
delayMs: 100
});
app.post("/reset-password/", resetPasswordSpeedLimiter, function(req, res) {
});
req.slowDown
A req.slowDown
property is added to all requests with the following fields:
limit
: The options.delayAfter value (defaults to 1)current
: The number of requests in the current windowremaining
: The number of requests remaining before rate-limiting beginsresetTime
: When the window will reset and current will return to 0, and remaining will return to limit (in milliseconds since epoch - compare to Date.now()). Note: this field depends on store support. It will be undefined if the store does not provide the value.delay
: Amount of delay imposed on current request (milliseconds)
Configuration
-
windowMs: milliseconds - how long to keep records of requests in memory. Defaults to 60000
(1 minute).
-
delayAfter: max number of connections during windowMs
before starting to delay responses. Number or function that returns a number. Defaults to 1
. Set to 0
to disable delaying.
-
delayMs: milliseconds - how long to delay the response, multiplied by (number of recent hits - delayAfter
). Defaults to 1000
(1 second). Set to 0
to disable delaying.
-
maxDelayMs: milliseconds - maximum value for delayMs
after many consecutive attempts, that is, after the n-th request, the delay will be always maxDelayMs
. Important when your application is running behind a load balancer or reverse proxy that has a request timeout. Defaults to Infinity
.
{
delayAfter: 1,
delayMs: 1000,
maxDelayMs: 20000,
}
-
skipFailedRequests: when true
failed requests (response status >= 400) won't be counted. Defaults to false
.
-
skipSuccessfulRequests: when true
successful requests (response status < 400) won't be counted. Defaults to false
.
-
keyGenerator: Function used to generate keys. By default user IP address (req.ip) is used. Defaults:
function (req ) {
return req.ip;
}
-
skip: Function used to skip requests. Returning true from the function will skip limiting for that request. Defaults:
function () {
return false;
}
-
onLimitReached: Function to listen the first time the limit is reached within windowMs. Defaults:
function (req, res, options) {
}
-
store: The storage to use when persisting rate limit attempts. By default, the MemoryStore is used.
- Note: when using express-slow-down and express-rate-limit with an external store, you'll need to create two instances of the store and provide different prefixes so that they don't double-count requests.
License
MIT © Nathan Friedly