简体   繁体   English

express-rate-limit - 捕获消息

[英]express-rate-limit - catching the message

In my application, I would like to be able to catch the message that is being produced by the express-rate-limit package.在我的应用程序中,我希望能够捕获由 express-rate-limit package 生成的消息。 This is an example of the code I have.这是我拥有的代码示例。 I would like to be able to catch the message part with middleware so I can post-process it (in this case I have multiple languages ).我希望能够使用中间件捕获消息部分,以便可以对其进行后处理(在这种情况下,我有多种语言)。

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

and then接着

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

I have a similar solution middleware setup for some of my other API messages:我为其他一些 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
    });
});

However, when trying to read a message from the express-rate-limit package it does not seem to be passing via this middleware at all.但是,当尝试从 express-rate-limit package 读取消息时,它似乎根本没有通过这个中间件。 I guess it's because it happens before it can even reach any API and trigger this middleware.我想这是因为它发生在它甚至可以到达任何 API 并触发这个中间件之前。

Looking at the res part passing through, I can see there is an object with the following data:查看通过的 res 部分,我可以看到有一个 object 具有以下数据:

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

But that does not seem to be transporting the message object that is set at the very top in the apiCreatingAccountLimiter.但这似乎并没有传输设置在 apiCreatingAccountLimiter 最顶部的消息 object。 I wonder how could I get to it?我想知道我怎么能得到它?

Does anyone know how this can be done?有谁知道如何做到这一点? I do not want those messages to be translated on the front end.我不希望在前端翻译这些消息。 I need the translation to happen on the NodeJS server.我需要在 NodeJS 服务器上进行翻译。 I am only interested in the middleware part where I can catch the message and post-process it.我只对可以捕获消息并对其进行后处理的中间件部分感兴趣。

In reading the source code , instead of using another middleware, you should play with the handler options as an option.在阅读源代码时,您应该使用处理程序选项作为选项,而不是使用另一个中间件。

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

At this end, you'll find an extract of the source code最后,您将找到源代码的摘录

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

I found that my frontend was only able to catch the message if I set the statusCode to 200, even though technically it should be a 429. So try this instead:我发现我的前端只有在我将 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'
  }
});

I did my best to match what you already had.我尽力匹配你已经拥有的。 Personally mine just looks like this basically:就我个人而言,基本上是这样的:

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.'
   }
})

Then, on my frontend I just check for res.data.error when the response comes in, and display that to the user if it exists.然后,在我的前端,我只是在响应进来时检查 res.data.error,如果存在,则将其显示给用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM