Как ограничить количество запросов POST по IP используя PHP или Apache?
Есть готовый webhook который принимает POST-запросы с указанных IP-адресов, при поступлении запроса проходит проверка данных, после чего они вносятся в MySQL. IP-адреса вносятся руками, но тем не менее, для полной автоматизации процесса, хотелось бы добавить ограничение. Необходимо ограничить количество запросов до 1 в 10 минут используя PHP или Apache. Подскажите как можно это реализовать?
Алгоритм примерно следующий:
При получении запроса пытаемся открыть файлик $_SERVER['REMOTE_ADDR'] . ".lock", т.е. название это IP клиента ("89.108.13.56.lock", "127.0.0.1.lock" и т.д.)
Далее читаем Unix timestamp из этого файла, если не прошло 10 минут - die().
Если прошло 10 минут и больше, то кидаем в файлик текущий Unix timestamp и работаем дальше!
С БД конечно правильнее было бы, но раз такой случай, то можно использовать мой метод.
Спасибо. Вариант с БД есть, хочу от него отказаться и посмотреть как это отразится на производительности. В случае чего всегда можно вернуть обратно. За подсказку с .lock файлами, спасибо.
# TZWatafak | qna.Habr.com
$ip = $_SERVER['REMOTE_ADDR']; # Получаем ip клиента.
$path = __DIR__ . '/'; # создаем переменную с путём к скрипту.
if(file_exists($path. $ip.'.lock')){ # Если файл с таким ip существует.
$times = intval(file_get_contents($path. $ip.'.lock')); # Получаем строковый timestamp и конвертируем в int
$sec = time() - $times; # получаем цифру сколько прошло секунд.
echo 'Секунды: '. $sec .'<br>'; # отображение на экран.
echo 'Минуты: '. round($sec / 60, 2).'<br>'; # отображение на экран.
if($sec < 60){
echo 'Еще нельзя делать запрос, не прошло 60 сек, осталось: '. (60 - $sec).' секунд';
}else{
echo 'Прошло больше 60 сек, значит можно делать запрос';
file_put_contents($path . $ip .'.lock',time());
}
}else{
file_put_contents($path . $ip .'.lock',time()); # Если файла не существует создаем и кладем в него время.
header("Location: /time.php");
}
бд вести учет времени последнего POST. Приходит новый POST, запрашиваем из бд время последнего POST, сравниваем с текущим, если время меньше 10 минут, то шлем POST лесом, иначе обрабатываем
Как уже ответил выше, вариант с отдельной таблицей IP - Дата последнего обращения есть, но хотелось бы вовсе не трогать БД если таймаут еще не прошел.
Например если IP не разрешен, то отдаю http_response_code(401);die();.