【问题标题】:Node js Rate Limit节点js速率限制
【发布时间】:2018-06-08 22:28:08
【问题描述】:

我正在尝试使用 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); 

【问题讨论】:

  • 这看起来很奇怪。您想将某人限制为每年 5 次请求?抱歉,但这与速率限制无关。那是另一回事。这就是为什么您找不到速率限制器来执行此操作的原因。速率限制通常是将某人限制为每分钟 5 个请求。看来您只是想限制有多少人可以使用您的服务。如果是这种情况,那么您只需要保留某种会话使用计数器,您可以为每个用户持久存储并检查每个操作。这不是速率限制。
  • 而且,要在长达一年的时间内强制执行某些操作,您还必须使用持久存储,这将再次排除速率限制选项。
  • 而且,您必须使用某种持久的用户 ID(通过登录验证)作为密钥。
  • 我正在使用第 3 方供应商,每次成功通话向我收取 0.95 美元的费用。它使写信自动化。我正在建立一项服务,允许人们给当地代表写一封信,我在一定程度上资助了这封信。我不想堆积账单。其次,我没有资源来构建数据库和管理用户信息。因此,速率限制。
  • 你不会找到一个可以工作一年的速率限制模块。你不会的。因为您的服务器不太可能在一年之内永远不会重新启动,所以您必须对操作进行持久存储。而且,您还必须通过一些持久的用户 ID 来跟踪它们。这些是满足您的需求的要求。这不是速率限制的作用。您在错误的池塘中寻找解决方案。而且,您还需要持久的用户 ID 来可靠地跟踪这一点(某种登录系统),因此您也必须具有持久性。

标签: javascript node.js api rate-limiting


【解决方案1】:

express-rate-limit 使用的内存存储实现使用setTimeout()windowMs 毫秒后清除存储。

根据Node.js documentation for setTimeout()

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

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

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

【讨论】:

  • 谢谢。您是否推荐任何其他速率限制器?由于缺乏资源,我不想创建自己的持久存储。
  • 我不能推荐一些具体的东西,但README of express-rate-limit中提到了其他一些。
  • OP 的问题根本不在于速率限制。他们需要一种完全不同类型的解决方案,因为任何速率限制器都不太可能满足他们的时间和持久性需求。
【解决方案2】:

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

https://www.ratelim.it/documentation/once_and_only_once 更进一步,让您在每个“无限”中执行 N 次,这非常有用。

您应该能够使用这项服务每年做 5 次。 (我运行 ratelim.it)。

【讨论】:

    【解决方案3】:

    rate-limiter-flexible 与 Mongo 的包可以帮助设置 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      • 2020-08-02
      • 2019-12-25
      • 2018-02-16
      • 1970-01-01
      相关资源
      最近更新 更多