express-limit-api
v0.0.4
Published
Litmit request as middleware for express
Downloads
3
Maintainers
Readme
Express rate-limiter
Rate limiting middleware for Express applications built on redis
npm install express-limit-api --save
var express = require("express");
var app = express();
var client = require("redis").createClient();
var limiter = require("express-limit-api")(app, client);
app.get(
"/api/action",
limiter({
path: "/api/action",
method: "get",
lookup: ["connection.remoteAddress"],
// 1000 requests per hour
total: 1000,
expire: 1000 * 60 * 60
}),
function(req, res) {
res.send(200, "Welcome to limit request api");
}
);
API options
limiter(options);
path
:String
optional route path to the requestmethod
:String
optional http method. acceptsget
,post
,put
,delete
, and of course Express'all
lookup
:Function|String|Array.<String>
value lookup on the request object. Can be a single value, array or function. See examples for common usagestotal
:Number
allowed number of requests before getting rate limitedexpire
:Number
amount of time inms
before the rate-limited is resetwhitelist
:function(req)
optional param allowing the ability to whitelist. returnboolean
,true
to whitelist,false
to passthru to limiter.skipHeaders
:Boolean
whether to skip sending HTTP headers for rate limits ()ignoreErrors
:Boolean
whether errors generated from redis should allow the middleware to call next(). Defaults to false.onRateLimited
:Function
called when a request exceeds the configured rate limit.
Examples
// Limit by IP address
limiter({
...
lookup: 'connection.remoteAddress'
...
})
// or if you are behind a trusted proxy (like nginx)
limiter({
lookup: 'headers.x-forwarded-for'
})
// by user (assuming a user is logged in with a valid id)
limiter({
lookup: 'user.id'
})
// limit your entire app
limiter({
path: '*',
method: 'all',
lookup: 'connection.remoteAddress'
})
// limit users on same IP
limiter({
path: '*',
method: 'all',
lookup: ['user.id', 'connection.remoteAddress']
})
// whitelist user admins
limiter({
path: '/delete/thing',
method: 'post',
lookup: 'user.id',
whitelist: function (req) {
return !!req.user.is_admin
}
})
// skip sending HTTP limit headers
limiter({
path: '/delete/thing',
method: 'post',
lookup: 'user.id',
whitelist: function (req) {
return !!req.user.is_admin
},
skipHeaders: true
})
// call a custom limit handler
limiter({
path: '*',
method: 'all',
lookup: 'connection.remoteAddress',
onRateLimited: function (req, res, next) {
next({ message: 'Rate limit exceeded', status: 429 })
}
})
// with a function for dynamic-ness
limiter({
lookup: function(req, res, opts, next) {
if (validApiKey(req.query.api_key)) {
opts.lookup = 'query.api_key'
opts.total = 100
} else {
opts.lookup = 'connection.remoteAddress'
opts.total = 10
}
return next()
}
})
as direct middleware
app.post("/user/update", limiter({ lookup: "user.id" }), function(req, res) {
User.find(req.user.id).update(function(err) {
if (err) next(err);
else res.send("ok");
});
});