@maryaTurova

Как ограничить количество запросов от одного IP юзера?

У меня имеется API. От пользователей приходят разные запросы по информации баланса и прочего.
Хотелось бы от всяких "членовредителей" поставить лимит на количество запросов в секунду, скажем при более 20 запросов в сек. выдать ответом "MAX_USER_TURN" и заблочить на 10 секунд.
Как и какими средствами это делается?
  • Вопрос задан
  • 67 просмотров
Решения вопроса 1
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Простой вариант.

<?php
session_start(); // в апи не должно быть сессии. Но вордпресс так не думает.

$hour = date('Y-m-d H');
$minute = floor(date('i') / 10);
$key = $hour . '_' . $minute;

$counts = $_SESSION['throttle'][ $ip ] ?? []; // получаем сохраненное
$count = $counts[ $key ] ?? 0; // берем по временной марке "сейчас"
$count++; // увеличиваем на единицу
$counts = []; // чистим старые временные марки
$counts[ $key ] = $count; // сохраняем новую
$_SESSION['throttle'][ $ip ] = $counts; // закидываем обратно в ящик

// проверяем, достигнут ли лимит
if ($count >= $limit) {
  throw new \RuntimeException('Throttling limit exceeded');
}


Более правильный вариант, особенно в апи:

composer require symfony/cache

<?php
require_once __DIR__ . '/vendor/autoload.php';

$cache = new FilesystemCache('throttle', null, __DIR__ . '/cache');

$hour = date('Y-m-d H');
$minute = floor(date('i') / 10);
$key = $hour . '_' . $minute;

$cacheItem = $cache->getItem($ip);
$counts = $cacheItem->isHit() ? $cacheItem->get() : [];
$count = $counts[ $key ] ?? 0;
$count++;
$counts = [];
$counts[ $key ] = $count;
$cacheItem->save($counts);

if ($count >= $limit) {
  throw new \RuntimeException('Throttling limit exceeded');
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Maksclub
@Maksclub Куратор тега PHP
maksfedorov.ru
Смотрите в сторону Rate Limiter

Визуальное объяснение разных алгоритмов: https://habr.com/ru/post/448438/

Имплеменатции на PHP на гитхабе:
https://github.com/search?l=PHP&q=rate+limiter&typ...
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы