Raz Buchnik
Raz Buchnik

Reputation: 8411

Node.js HTTP how to do an HTTP request rate limit?

I want to create a rate limit middleware for my express http handling, something like this:

app.post("/v1/authentication/login", rateLimiter(5, 20), require('./api/v1-login'));

Which the middleware will allow only 5 requests whitin 20 seconds.

I can use a plugin for that, but I am also working with clusters/processes and I have read that the plugin would not support processes.

I know I can share data between processes using a DB - MongoDB or Redis.

In addition I would like to make a custom rate limit - that means, for function A I want user John to be allowed to request 5 times in every 20 seconds for example, however, for the same function I want Dani to be allowed to send 10 requests per 20 seconds.

I also need this to be applied in all of the processes as I mentioned before.

I thought about writing my own script of saving the data of the requesting user, but I do not know what to exactly save - his IP? his chrome serial number or what ever it is..?

Should I store this in the Redis DB or Mongo? Maybe is there a Node.js built in memory which is better to save there the data instead?

What do you recommend?

Upvotes: 3

Views: 7840

Answers (3)

Animir
Animir

Reputation: 1204

rate-limiter-flexible allows to setup different limits for different users.

It works in Cluster without any DB, MongoDB or Redis.

Read about login endpoints protection here login endpoints protection here

Upvotes: 0

Zlatko
Zlatko

Reputation: 19588

There's nothing wrong to using a plugin. Take express-rate-limit with Redis Store for example, you can rate-limit the whole app per user IP and store this in Redis:

const rateLimit = require("express-rate-limit");
const RedisStore = require('rate-limit-redis');
app.use(rateLimit({
  store: new RedisStore({ /* ... config */ });
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
});

Or you can limit just a given endpoint:

const someApiLimiter = rateLimit({
  windowMs: 5 * 60 * 1000,
  max: 12,
});
app.use('/api/some', someApiLimiter);

By default req.ip is used, but you can provide a keyGenerator function, and use something like, say, combination of req.ip and req.user._id. So you're covered on all bases.

I recommend Redis for these things as it's a lot of small data that you need fast, Redis does these things well.

Upvotes: 3

Edrian
Edrian

Reputation: 608

I would recommend implementing a token-based authentication much like Facebook's API. That way you can monitor who is using the API and identify each user.

When that is implemented, you can then start limiting the calls based on the user (the one who owns the token) who is calling the API on the time period of your liking.

Upvotes: 0

Related Questions