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