express-rate-limit blocking requests from all users

Viewed 2478

I'm using express-rate-limit npm package, I deployed my backend on AWS (t2 micro ec2 instance), while limiter is on, requests are blocked from ALL users who try to interact with my API, it works for a couple of minutes and stops for about 10 minutes. when I comment out the limiter part everything is working fine,I think too many requests should be blocked for only one user who tries to hammer the server with requests but what happens is ALL users get blocked, all users are treated like only 1 user, that's my conclusion.

If that's the case what should I do? I need my rate limiter on, and if there is any other explanation what would it be?

3 Answers

By default, express-rate-limit has a keyGenerator of req.ip. When I log this on my server it is '::ffff:127.0.0.1' which is obviously going to be the same for every request, thus limiting for all IP addresses once it's limited for one.

My solution was to use request-ip to get the correct IP address like so:

const rateLimit = require('express-rate-limit');
const requestIp = require('request-ip');

const app = express();

app.use(requestIp.mw());

app.use(rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 30, // limit each IP to 30 requests per windowMs
  keyGenerator: (req, res) => {
    return req.clientIp // IP address from requestIp.mw(), as opposed to req.ip
  }
}));

The express-rate-limit package blocks requests based on IP Address and that's because it provides a very basic configuration for rate-limiting that would be suitable for most applications. If you block based on user, someone can easily configure a bot to hit your APIs until the limit is reached on one user account and make a new account automatically to start hitting your server again. Blocking based on IP avoids such risks as one IP means one Device no matter how many users request from that IP. In most cases, one device is most likely to be used by one person so this solution works pretty well.

keyGenerator: function (req: any) {
    return req.headers["x-forwarded-for"] || req.connection.remoteAddress; 
}

It blocks based on iP

Related