Node Express оборачивает POST-запрос счетчиком и выдает ошибку после x

Я работаю над проектом Node Express/Angular Civic, который интегрирован со сторонним API. Каждый звонок стоит мне 1 доллар. Я финансирую определенную часть этого, но затем я бы хотел, чтобы запрос POST для третьей стороны прекратился. Причина в том, что я не хочу платить тысячи долларов. Сторонний API не поддерживает ограничение скорости.

Я могу создать базу данных или создать аутентификацию, но предпочитаю не идти по этому пути и не интегрировать платежный шлюз. Но я не предпочитаю ни одно из этих решений по личным причинам. Я столкнулся с частичным решением / узлом-модулем (express-rate-limit), который ограничивает IP-адрес. Но это по-прежнему не решает проблему прекращения отправки запросов после достижения x количества вызовов.

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

app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)

var apiLimiter = new RateLimit({
  windowMs: 15*60*1000, // 15 minutes
  max: 1, // 1 call every 15 minutes
  delayMs: 0 // disabled
});

// only apply to requests that begin with /api/
app.use('/api/', apiLimiter);

Есть ли лучшие решения / лучшие практики? Это просто побочный проект, который может помочь нескольким людям, но я не хочу разориться, взяв на себя расходы, если многие люди начнут его использовать. Спасибо!

2 ответа

Уже немного поздно, но я бы посоветовал вам использовать более гибкую библиотеку -гибко ограничивающую скорость для ограничения скорости.

const rateLimiter = new RateLimiterMemory(
  {
      points: 1,
      duration: 15 * 60,
  }
);

router.get('/your-endpoint', (req, res, next) => {
  rateLimiter.consume(req.connection.remoteAddress)
    .then(() => {
      // Request to 3-rd party API here
    })
    .catch((rejRes) => {
      const secs = Math.round(rejRes.msBeforeNext / 1000) || 1;
      res.set('Retry-After', String(secs));
      res.status(429).send('Too Many Requests');
      // Or you can suggest to pay here and then use 
      // rateLimiter.reward() , see README
  });
});

Вы также можете использовать Cluster, Redis или же Mongo ограничители из той же библиотеки, если вам это нужно в кластере или распределенном приложении

Как сказал Джордан, установите const и верните константу. Он будет поддерживать состояние ограничения скорости на разных IP-адресах.

const keyIp = "127.0.0.1";

var limiter = new RateLimit({
  windowMs: 2147483647, // store key for node max
  max: 3, // limit each IP to 1 requests per windowMs
  // delayMs: 24*60*60*60, // delaying - 24 hours
  message: "Sorry, the maximum limit of 50 letters sent has been reached. Thank you for participating!",
  keyGenerator: function (req, res) {
        return keyIp;
  }
});

app.use('/api/letter', limiter);
Другие вопросы по тегам