节点js速率限制

时间:2017-02-26 13:10:23

标签: javascript node.js api rate-limiting

我正在尝试使用express-rate-limit在我的应用上设置API速率限制。如果来自相同的IP地址,它可以工作。一旦达到最大值5,我会收到一条错误消息。但是,当从不同的IP地址/计算机尝试它时,它会失败。知道如何解决这个问题吗?我尝试使用127.0.0.1来生成密钥,无论哪个IP地址,但也失败了。

以下是我的代码:

// Rate Limit
var RateLimit = require('express-rate-limit');

app.enable('trust proxy');

var limiter = new RateLimit({
  windowMs: 365*24*60*60*1000, // 1 year
  max: 5, // limit each IP to 1 requests per windowMs
  delayMs: 365*24*60*60*1000, // delaying - 365 days until the max limit is reached
  message: "Sorry, the maximum limit of 50 letters sent has been reached. Thank you for participating!",
  keyGenerator: function (req) {
    req.ip = "127.0.0.1";
    // req.ip = "ip address";
    return req.ip;
  }
});

app.use('/api/letter', limiter); 

3 个答案:

答案 0 :(得分:4)

#nav{ padding: 3px; font-family: Helvetica; list-style-type: none; position: absolute; width: 100%; } 使用的内存存储实现使用express-rate-limitsetTimeout()毫秒后清除存储。

根据Node.js https://jsfiddle.net/1ngotz5u/

  

当延迟大于2147483647或小于1时,延迟将设置为1.

在您的情况下,延迟大于该数量,即 31536000000 毫秒。这导致商店永远不会存储超过1毫秒的任何数据。

要解决这个问题,您可能必须实现自己的商店(请参阅documentation for setTimeout()选项),或者寻找没有此限制的替代速率限制器(在我看来,这么大到期时间,无论如何你都需要某种持久性存储。)

答案 1 :(得分:0)

我认为将这种情况称为“速率限制”是完全合理的。仅仅因为时间段很长(每年)并不意味着它不是每个时间段的限制。

https://www.ratelim.it/documentation/once_and_only_once进一步采取这种做法,让你做出N次"无限"这是非常有用的。

您应该可以使用此服务每年执行5次。 (我运行ratelim.it)。

答案 2 :(得分:0)

Mongo的

rate-limiter-flexible包可以帮助设置1年的费率限制

const { RateLimiterMongo } = require('rate-limiter-flexible');
const { MongoClient } = require('mongodb');

const mongoOpts = {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
  reconnectInterval: 100, // Reconnect every 100ms
};

const mongoConn = MongoClient.connect(
  'mongodb://localhost:27017',
  mongoOpts
);

const opts = {
  mongo: mongoConn,
  points: 5, // Number of points
  duration: 365*24*60*60, // Per 1 year
};

const rateLimiter = new RateLimiterMongo(opts);

app.use('/api/letter', (req, res, next) => {
  rateLimiter.consume(req.ip)
    .then(() => {
      next();
    })
    .catch((rejRes) => {
      res.status(429).send('Too Many Requests');
  });
);

还建议设置insuranceLimiter并阻止策略。阅读更多here