Исключения с ограничением скорости в промежуточном ПО Express?

#express #exception #rate-limiting

#экспресс #исключение #ограничение скорости

Вопрос:

В Express.js приложение, мы хотели бы ограничить скорость пользователей, которые слишком часто посещают определенный маршрут, но только если они вызывают определенное исключение. Есть ли естественный способ сделать это в Express?

Вот более или менее то, что мы имеем сейчас, без ограничения скорости.

 app.get(
    "/api/method", 
    authenticationMiddleware, 
    handler
);
  

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

 app.get(
    "/api/method", 
    authenticationMiddleware, 
    rateLimiterMiddleware,   # <--- count, and tell them to go away if over limit
    handler
);
  

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

В Express обработчики ошибок должны находиться в конце цепочки обработчиков.

Итак, похоже, нам нужно поставить «защиту» в начале, а «счетчик» обработки ошибок — в конце.

 app.get(
    "/api/method", 
    authenticationMiddleware, 
    errorIfTooManyExceptionsByUser,   # <--- tell them to go away if over the limit
    handler, 
    countExceptionsForUser            # <--- count
);
  

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

Возможно, мы могли бы поумнеть и модифицировать обработчики, чтобы выполнять защиту и подсчет до и после их запуска?

 app.get(
   "/api/method", 
   authenticationMiddleware,
   rateLimitErrors(handler)   # <-- ???
)
  

Я что-то упускаю или есть лучший способ сделать это?

Ответ №1:

Возможно, вы можете посмотреть, как express-redis-cache обрабатывает свое промежуточное программное обеспечение ( https://github.com/rv-kip/express-redis-cache/blob/df4ed8e057a5b7d41d894e6e468f975aa62206f6/lib/ExpressRedisCache/route.js#L184). Они оборачивают send() метод express своей собственной логикой. Возможно, при этом у вас может быть только одно промежуточное программное обеспечение, но я думаю, что это не лучшее решение.

Ограничение скорости Express

Существует промежуточное программное обеспечение, которое обрабатывает ограничение скорости в express https://www.npmjs.com/package/express-rate-limit.

Обработка Nginx

Express — это облегченный фреймворк, в официальном документе они советуют установить Nginx перед вашим сервером Express для обработки серверных задач.

(https://expressjs.com/en/advanced/best-practice-performance.html)

Использовать обратный прокси

Обратный прокси-сервер находится перед веб-приложением и выполняет вспомогательные операции с запросами, помимо направления запросов в приложение. Помимо прочего, оно может обрабатывать страницы ошибок, сжатие, кэширование, обслуживание файлов и балансировку нагрузки.

Передача задач, не требующих знания состояния приложения, обратному прокси освобождает Express для выполнения специализированных прикладных задач. По этой причине рекомендуется запускать Express через обратный прокси-сервер, такой как Nginx или HAProxy, в рабочей среде.

А в nginx у вас есть система с ограничением скорости: https://www.nginx.com/blog/rate-limiting-nginx /. Я не знаю, можете ли вы настроить это для вашего конкретного варианта использования, но я думаю, что это лучший способ справиться с ограничением скорости.