Omar Zahir
Omar Zahir

Reputation: 215

express-rate-limit blocking requests from all users

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?

Upvotes: 5

Views: 9115

Answers (4)

If you properly follow guideline usage of express rate limit npm package AND you are using nginx proxy (proxy_pass)

For instance: express rate limit usage

const rateLimit = require('express-rate-limit');
const app = express();
const limiter = rateLimit({
  windowMs: 10 * 60 * 1000, // 10mins,
  max: 500,
  message: "Too many requests, please try again later.",
});

Possible error could be in your nginx script.
=> you need to expose the actual client IP. Add this config to your nginx config:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

For example:

location /api {
        proxy_pass http://localhost:5555; #whatever port your app runs on
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        ....
}

Then restart nginx server

sudo nginx -t
sudo systemctl reload nginx
sudo service nginx restart

Finally, try again. Hope this help!

Upvotes: 2

FBC
FBC

Reputation: 1132

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

It blocks based on iP

Upvotes: 2

kmanzana
kmanzana

Reputation: 1198

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
  }
}));

Upvotes: 12

Ahmad
Ahmad

Reputation: 11

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.

Upvotes: 1

Related Questions