我正在做一个与第三方API集成的Node Express/Angular Civic项目。每次通话的费用是1.00美元。我正在资助它的某一部分,但然后我希望第三方的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);是否有更好的解决方案/最佳实践?这只是一个辅助项目,可以帮助几个人,但如果有很多人开始使用它,我不想因为承担成本而破产。谢谢!
发布于 2017-02-26 23:29:40
就像乔丹说的,设置一个常量并返回常量。它将维护跨不同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);发布于 2018-05-13 18:53:24
现在有点晚了,但我建议您使用更灵活的库rate-limiter-flexible来进行速率限制。
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限制器
https://stackoverflow.com/questions/42164441
复制相似问题