Redis express rate limiter
Version requirements
- Express 4 is needed for the new router
- Redis 2.6.12 and above is needed to support the PX modifier on Set commands
- A redis client to pass-in that supports
multi
andset
commands (I recommend https://github.com/NodeRedis/node_redis)
npm install redis-express-rate-limiter --save
Simple Example:
const express = // please use version 4+const app =const client =const rateLimiter =const limiterConfigs =path: '/forgot-password'method: 'post'limitBy: 'body.email'// 50 requests per hourtotal: 50// time is in millisecondsexpiresIn: 1000 * 60 * 601resresresapp //you can also use many limiters each for a different route!app
API options aka limiterConfigs
path
:String
route path to the requestmethod
:String
http method. acceptsget
,post
,put
,delete
, and of course Express'all
limitBy
:String
property(s) to call on the express request object to use for the key for rate limitingtotal
:Number
allowed number of requests before getting rate limitedexpiresIn
:Number
amount of time inms
before the rate-limited is resetgenStored
:function(req)
returning anObject
. Each key in the object is stored as a redis key (in addition to the counter) and can be used in decrementAmount for custom logicdecrementAmount
:function(req, redisInfo)
returning aNumber
. Used to determine how much to decrement a user's total amount for each attempt. Allows for custom logic to reflect i.e. use a return value of 0 for a whitelistonRateLimited
:function(req, res, next)
called when a request exceeds the configured rate limit.onError
:function(err, req, res, next)
called when a redis error occurs.onPassThrough
:function(res)
called when a request doesn't get rate limited.
Examples
// limit by IP addresslimiterConfigs =...limitBy: 'connection.remoteAddress'...// or if you are behind a trusted proxy (like nginx)limiterConfigs =...limitBy: 'headers.x-forwarded-for'...// limit your entire applimiterConfigs =path: '*'method: 'all'...limitBy: 'connection.remoteAddress'...// whitelist all admins with a very bad admin schemelimiterConfigs =path: '/forgot-password'method: 'post'expiresIn: 1000 * 60 * 60{if reqbodyadmin return 0return 1}...
Special Thanks
https://github.com/ded/express-limiter and ded for inspiration and some of the initial ideas