What is express-rate-limit?
The express-rate-limit npm package is a middleware for Express applications that enables rate limiting to prevent abuse by restricting the number of requests a client can make in a given time frame. It is useful for preventing brute force attacks, DDoS attacks, and to generally control the traffic to an API or web application.
What are express-rate-limit's main functionalities?
Basic rate-limiting
This feature sets up basic rate-limiting on an Express application, limiting clients to a specified number of requests within a time frame.
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
// Apply to all requests
app.use(limiter);
Custom message
This feature allows customization of the message sent back to the client when the rate limit is exceeded.
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
message: 'Too many requests, please try again later.'
});
app.use(limiter);
Skip certain requests
This feature allows some requests to bypass the rate limit, based on a condition such as a specific IP address.
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
skip: function (req, res) {
return req.ip === '123.123.123.123';
}
});
app.use(limiter);
Customize response headers
This feature enables sending HTTP headers to the client with information about their current rate limit status.
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
headers: true
});
app.use(limiter);
Other packages similar to express-rate-limit
ratelimiter
The 'ratelimiter' package is similar to 'express-rate-limit' but uses Redis for storing rate limit data, which makes it suitable for distributed applications. It is more complex to set up due to the dependency on Redis.
express-brute
The 'express-brute' package provides rate limiting with a focus on preventing brute-force attacks. It offers more customization options for handling lockouts and has a pluggable store system, which can be more flexible than 'express-rate-limit'.
express-slow-down
The 'express-slow-down' package is similar to 'express-rate-limit' but instead of blocking requests after a limit is reached, it slows down the response times. It's useful for slowing down repeated requests rather than completely blocking them.
Express Rate Limit
Basic rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.
Note: this module does not share state with other processes/servers by default.
If you need a more robust solution, I recommend adding the Redis Store or checking out strict-rate-limiter or express-brute, both are excellent pieces of software.
Install
$ npm install --save express-rate-limit
Usage
For an API-only server where the rate-limiter should be applied to all requests:
var RateLimit = require('express-rate-limit');
app.enable('trust proxy');
var limiter = new RateLimit({
windowMs: 15*60*1000,
max: 100,
delayMs: 0
});
app.use(limiter);
For a "regular" web server (e.g. anything that uses express.static()
), where the rate-limiter should only apply to certain requests:
var RateLimit = require('express-rate-limit');
app.enable('trust proxy');
var apiLimiter = new RateLimit({
windowMs: 15*60*1000,
max: 100,
delayMs: 0
});
app.use('/api/', apiLimiter);
Create multiple instances to apply different rules to different routes:
var RateLimit = require('express-rate-limit');
app.enable('trust proxy');
var apiLimiter = new RateLimit({
windowMs: 15*60*1000,
max: 100,
delayMs: 0
});
app.use('/api/', apiLimiter);
var createAccountLimiter = new RateLimit({
windowMs: 60*60*1000,
delayAfter: 1,
delayMs: 3*1000,
max: 5,
message: "Too many accounts created from this IP, please try again after an hour"
});
app.post('/create-account', createAccountLimiter, function(req, res) {
});
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. 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. - max: max number of connections during
windowMs
milliseconds before sending a 429 response. Defaults to 5
. Set to 0
to disable. - message: Error message returned when
max
is exceeded. Defaults to 'Too many requests, please try again later.'
- statusCode: HTTP status code returned when
max
is exceeded. Defaults to 429
. - headers: Enable header to show request limit and current usage
- keyGenerator: Function used to generate keys. By default user IP address (req.ip) is used. Defaults:
function (req ) {
return req.ip;
}
- handler: The function to execute once the max limit is exceeded. It receives the request and the response objects. The "next" param is available if you need to pass to the next middleware. Defaults:
function (req, res, ) {
res.format({
html: function(){
res.status(options.statusCode).end(options.message);
},
json: function(){
res.status(options.statusCode).json({ message: options.message });
}
});
}
- store: The storage to use when persisting rate limit attempts. By default, the MemoryStore is used. It must implement the following in order to function:
function SomeStore() {
this.incr = function(key, cb) {
};
this.resetKey = function(key) {
};
};
Avaliable data stores are:
- MemoryStore: (default)Simple in-memory option. Does not share state when app has multiple processes or servers.
- rate-limit-redis: Redis-backed store, more suitable for large or demanding deployments.
The delayAfter
and delayMs
options were written for human-facing pages such as login and password reset forms.
For public APIs, setting these to 0
(disabled) and relying on only windowMs
and max
for rate-limiting usually makes the most sense.
Instance API
- resetKey(key): Resets the rate limiting for a given key. (Allow users to complete a captcha or whatever to reset their rate limit, then call this method.)
v2 changes
v2 uses a less precise but less resource intensive method of tracking hits from a given IP. v2 also adds the limiter.resetKey()
API and removes the global: true
option.
License
MIT © Nathan Friedly