#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 /. Я не знаю, можете ли вы настроить это для вашего конкретного варианта использования, но я думаю, что это лучший способ справиться с ограничением скорости.