Mechanizm Antiflood – jak działa i jak go zaimplementować w PHP
Flooding to sytuacja, w której użytkownik (lub zautomatyzowany bot) wysyła wiele żądań w krótkim czasie, przeciążając serwer lub nadużywając jego funkcji. Aby temu zapobiec, można wdrożyć mechanizm antiflood, który kontroluje liczbę żądań od danego użytkownika w określonym czasie.
Poniżej omówiono działanie mechanizmu antiflood oraz przedstawiono przykładową implementację w PHP.
Jak działa mechanizm Antiflood?
-
Rejestracja żądań: Mechanizm monitoruje liczbę żądań wysyłanych przez konkretnego użytkownika. Można to robić na podstawie adresu IP, identyfikatora sesji lub tokenu autoryzacyjnego.
-
Limit czasowy: System ustala okno czasowe (np. 10 sekund) i maksymalną liczbę dozwolonych żądań w tym czasie.
-
Blokada: Jeśli użytkownik przekroczy limit, jego żądania są odrzucane, a on sam może otrzymać wiadomość o zbyt częstych żądaniach (np. kod HTTP 429 – Too Many Requests).
- Czyszczenie danych: Po upływie określonego czasu zapisane dane są usuwane lub resetowane, co pozwala użytkownikowi kontynuować działanie w normalnym trybie.
Implementacja mechanizmu Antiflood w PHP
Poniższy kod przedstawia prosty system antiflood oparty na przechowywaniu danych w plikach tymczasowych lub tablicy w pamięci.
Przykładowy kod:
<?php
// Określenie limitów
$maxRequests = 5; // Maksymalna liczba żądań
$timeWindow = 10; // Okno czasowe w sekundach
// Identyfikacja użytkownika (np. na podstawie adresu IP)
$userIP = $_SERVER['REMOTE_ADDR'];
// Plik do przechowywania danych o żądaniach
$dataFile = sys_get_temp_dir() . "/antiflood_" . md5($userIP) . ".json";
// Odczyt istniejeących danych
if (file_exists($dataFile)) {
$data = json_decode(file_get_contents($dataFile), true);
} else {
$data = [];
}
// Aktualny czas
$currentTime = time();
// Filtrowanie starych wpisów
if (isset($data['timestamps'])) {
$data['timestamps'] = array_filter($data['timestamps'], function ($timestamp) use ($currentTime, $timeWindow) {
return ($currentTime - $timestamp) <= $timeWindow;
});
} else {
$data['timestamps'] = [];
}
// Sprawdzenie liczby żądań
if (count($data['timestamps']) >= $maxRequests) {
http_response_code(429); // Kod HTTP 429 - Too Many Requests
die("Zbyt wiele żądań. Spróbuj ponownie później.");
}
// Rejestracja nowego żądania
$data['timestamps'][] = $currentTime;
file_put_contents($dataFile, json_encode($data));
// Kontynuowanie obsługi żądania
echo "Witaj! Twoje żądanie zostało przyjęte.";
?>
Wyjaśnienie kodu
-
Identyfikacja użytkownika: Używany jest adres IP jako identyfikator użytkownika. W bardziej zaawansowanych systemach można stosować tokeny sesji lub identyfikatory użytkownika z bazy danych.
-
Przechowywanie danych: Dane o żądaniach są przechowywane w pliku JSON. Dla prostoty w tym przypadku wykorzystano folder tymczasowy serwera.
-
Czyszczenie danych: Stare wpisy są filtrowane, aby zachować tylko te z ostatniego okna czasowego.
-
Blokada: Jeśli liczba żądań przekracza ustalony limit, użytkownik otrzymuje odpowiedź z kodem 429.
- Rejestracja nowego żądania: Czas bieżącego żądania jest dodawany do listy.
Rozbudowa mechanizmu
-
Bazy danych: W przypadku większych systemów warto przechowywać dane o żądaniach w bazie danych (np. MySQL, Redis) w celu lepszej wydajności i skalowalności.
-
Zaawansowana identyfikacja: Poza adresem IP można uwzględnić nagłówki HTTP lub tokeny sesji, aby uniknąć problemu współdzielonych adresów IP.
-
Powiadomienia: W przypadku ciągłego naruszania limitów można wysyłać powiadomienia administratorowi lub automatycznie blokować adresy IP.
- Dynamiczne limity: Mechanizm może dostosowywać limity w zależności od czasu, rodzaju żądań czy obciążenia serwera.
Mechanizm antiflood jest istotnym elementem ochrony aplikacji internetowych przed przeciążeniem i nadużyciami. Prosta implementacja w PHP może skutecznie zabezpieczyć małe projekty, a w przypadku większych systemów warto rozważyć bardziej zaawansowane podejścia.