@man_without_face
студент

Чем и как ограничивать количество запросов к API?

Хочу дать доступ к своему API всем желающим, но боюсь придёт какой-то негодяй и положит своими запросами весь сервак. Как и чем можно ограничить клиента?

Конечно, самым простым способом вижу выдачу ключа и хранения в БД времени последнего запроса по этому ключу. Но что-то мне не нравится этот способ. Может есть что-то интереснее?
  • Вопрос задан
  • 1117 просмотров
Решения вопроса 2
@SmInc
Русофоб, украинофоб, хулиган, сумрачный гений
Если алгоритмически, то хранить последний запрос бесполезно. Что вы сделаете? Заставите перед каждым вызовом ставить Sleep, обломав всех, у кого слишком быстрый интернет? Бред...
Нужен счетчик запросов, обнуляющийся через какую-то единицу времени. Допустим если 10 минут не прошло, а запросов уже >100, то выдаем ошибку.
Можно типа "плавающего таймера". У него лимит запросов уменьшается с увеличением частоты запросов. А по мере простоя - увеличивается.

Решение использовать БД - нормально.

Банить не надо, просто выдавать ошибку. И выделить в документации, что установлен лимит и не следует слать запросы с граничащей с ним частотой (причем, с учетом идеально быстрого интернета у клиента). А в алгоритме его клиента непременно нужна ветка с обработкой ошибки limit exceed.
Но если у него цель именно ддосить, то на ошибку ему плевать. А отсекать запросы от забаненного - в php слишком поздно. Тут уже нужно что-то типа CDN - мощного сервера, который отправляет запрос на ваш сервер или отсекает. Но я не знаю, дружат ли CDN именно с API.

За $$$ можно увеличивать интервал обнуления счетчика. Тут уже был бы спрос. А в бесплатной демо-версии, если само API платное - можно уменьшить.
Ответ написан
rSedoy
@rSedoy
Python/Django
Один из простых способов - сделать ограничение веб-сервером, например у nginx через nginx.org/ru/docs/http/ngx_http_limit_req_module.html
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
Пользователи должны идентифицироваться: по ключу лучше всего.

Скажем, вы хотите установить лимит не более 10 запросов в 15 секунд.
Для учета можно использовать не БД а Redis.

Ключ - ключ API пользователя, значение - список. Хранить списки (Lists) timestamp'ом последних 10 запросов. Установить время жизни в 15 секунд.
При поступлении нового запроса смотреть, есть ли уже такой ключ и не более 10 записей в списке. Если меньше, дописывать в конец текущее время и разрешать выполнение запроса. Если 10 записей есть, но самая левая более 15 секунд назад, её можно стереть и справа вставить новую.
Ответ написан
Stalker_RED
@Stalker_RED
.
Еще можно отслеживать по ip и по user-agent и/или referer, например, смотря откуда запросы идут.
Но все это при желании обходится.
Самым правильным вариантом было бы организовать сервис так, чтобы он выдерживал нагрузку. А банить и троттлить только совсем уж злостных.

Вообще сложно рекомендовать что-то конкретное, вы же даже не написали на какой платформе у вас API крутится.
Ответ написан
@immaculate
Программист-путешественник
Как правило, в серьезных библиотеках для реализации REST API уже есть либо встроенная поддержка throttling, либо при помощи сторонних приложений. Например, в Django Rest Framework: Throttling
Ответ написан
thecoder
@thecoder
Разработчик веб-приложений и сервисов.
Для Go есть неплохая библиотека для подсчета рейтов: https://github.com/paulbellamy/ratecounter Пользователя хорошо бы ассоциировать с ключом, чтобы не заморачиваться с источниками трафика, а ключу сопоставить набор обновляемых счетчиков. Как хранить ключи и счетчики - дело вкуса. Если порог превышен, получите-распишитесь HTTP 429 Too Many Requests. Это если самому. Вообще библиотеки для REST часто это из коробки умеют.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы