表达速率限制-捕获消息

时间:2019-10-21 12:46:08

标签: node.js express middleware

在我的应用程序中,我希望能够捕获由express-rate-limit软件包生成的消息。这是我的代码示例。我希望能够使用中间件捕获消息部分,以便对其进行后处理(在这种情况下,我有多种语言)。

const apiCreatingAccountLimiter = rateLimit({
  windowMs: 10 * 60 * 1000, // 10 minutes
  max: 10, // limit each IP to 10 requests per windowMs
  message: {
    limiter: true,
    type: "error",
    message: 'maximum_accounts'
  }
});

然后

router.post('/signup', apiCreatingAccountLimiter, (req, res, next) => {
// handling the post request
})

对于其他一些API消息,我也有类似的解决方案中间件设置:

// error processing middleware
app.use((err, req, res, next) => {
    const statusCode = err.statusCode || 500;
    res.status(statusCode).send({
        type: 'error', 
        message: err.message, 
        fields: err.fields === '' ? '' : err.fields,
        code: err.code === '' ? '' : err.code,
        section: err.section === '' ? 'general' : err.section
    });
});

但是,当尝试从express-rate-limit包中读取消息时,它似乎根本没有通过此中间件传递。我猜这是因为它发生在它甚至没有达到任何API并触发此中间件之前。

查看通过的res部分,我可以看到有一个包含以下数据的对象:

rateLimit:
{ limit: 10,
current: 10,
remaining: 0,
resetTime: 2019-10-21T12:35:46.919Z 
},

但是,这似乎并没有传输在apiCreatingAccountLimiter中最顶部设置的消息对象。我不知道该怎么办?

有人知道该怎么做吗?我不希望这些消息在前端进行翻译。我需要翻译在NodeJS服务器上进行。我只对中间件部分感兴趣,我可以在其中捕获消息并对其进行后处理。

2 个答案:

答案 0 :(得分:2)

我发现,即使将statusCode设置为200,前端也只能捕获消息,即使从技术上讲应该是429。因此请尝试以下操作:

const apiCreatingAccountLimiter = rateLimit({
  windowMs: 10 * 60 * 1000, // 10 minutes
  max: 10, // limit each IP to 10 requests per windowMs,
  statusCode: 200,
  message: {
    status: 429, // optional, of course
    limiter: true,
    type: "error",
    message: 'maximum_accounts'
  }
});

我竭尽全力匹配您已经拥有的东西。我的个人基本上基本上是这样的:

const loginRatelimiter = rateLimit({
   windowMs: 6 * 60 * 1000,
   max: 10,
   statusCode: 200,
   message: {
    status: 429,
    error: 'You are doing that too much. Please try again in 10 minutes.'
   }
})

然后,在我的前端,我只在响应出现时检查res.data.error,并将其显示给用户(如果存在)。

答案 1 :(得分:0)

在阅读source code时,应该使用处理程序选项作为选项,而不是使用其他中间件。

const apiCreatingAccountLimiter = rateLimit({
  windowMs: 10 * 60 * 1000, // 10 minutes
  max: 10, // limit each IP to 10 requests per windowMs
  message: "my initial message",
      handler: function(req, res /*, next*/) {
        var myCustomMessage = require('anotherModuleYouWannaUse_ForExemple');
        res.status(options.statusCode).send(myCustomMessage);
      },
});

最后,您将找到源代码的一部分

function RateLimit(options) {
  options = Object.assign(
    {
      windowMs: 60 * 1000, // milliseconds - how long to keep records of requests in memory
      max: 5, // max number of recent connections during `window` milliseconds before sending a 429 response
      message: "Too many requests, please try again later.",
      statusCode: 429, // 429 status = Too Many Requests (RFC 6585)
      headers: true, //Send custom rate limit header with limit and remaining
      skipFailedRequests: false, // Do not count failed requests (status >= 400)
      skipSuccessfulRequests: false, // Do not count successful requests (status < 400)
      // allows to create custom keys (by default user IP is used)
      keyGenerator: function(req /*, res*/) {
        return req.ip;
      },
      skip: function(/*req, res*/) {
        return false;
      },
      handler: function(req, res /*, next*/) {
        res.status(options.statusCode).send(options.message);
      },
      onLimitReached: function(/*req, res, optionsUsed*/) {}
    },
    options
  );