Przejdź do głównej zawartości

29. API Rate Limiting

API Rate Limiting

Rate limiting to mechanizm ochrony API przed przeciążeniem: każdy klient może wykonać maksymalnie N żądań w danym oknie czasowym. Bez tego jeden użytkownik (lub bot) może zablokować serwis dla wszystkich. Ta prezentacja wyjaśnia jak działa, jakie są algorytmy i jak to zaimplementować w PHP.

  1. Dlaczego API potrzebuje rate limiting? — ochrona przed DDoS, boty, fair use
  2. Czym różni się token bucket od sliding window? — dwa podejścia algorytmiczne
  3. Co odpowiada serwer gdy limit jest przekroczony? — kod 429, nagłówki Retry-After
  1. Problem bez rate limiting — przykład ataku brute-force lub scraping
  2. Definicja: limit na IP, na klucz API, na użytkownika
  3. Algorytm: Fixed Window — prosty, ale podatny na burst
  4. Algorytm: Sliding Window — dokładniejszy, ciągłe okno
  5. Algorytm: Token Bucket — naturalne opóźnianie, burst allowance
  6. Odpowiedź HTTP 429 Too Many Requests z nagłówkami
  7. Implementacja w PHP z przechowywaniem stanu w pliku/APCu

Diagram algorytmu

Token Bucket lub Sliding Window — wizualizacja jak żetony są dodawane/konsumowane

Nagłówki HTTP

Przykład odpowiedzi 429 z nagłówkami X-RateLimit-Limit, Retry-After

Minimum:

  • Definicja rate limiting i po co go stosować
  • Przykład: 100 żądań na minutę na IP
  • Odpowiedź HTTP 429 z opisem

Forma: 10 slajdów, 10 minut

Ocena: 3.0
<?php
// Prosta implementacja Fixed Window Rate Limiter w PHP
// (przechowywanie w pliku JSON — do celów edukacyjnych)
function checkRateLimit(string $ip, int $limit = 10, int $window = 60): bool {
$file = sys_get_temp_dir() . '/rate_' . md5($ip) . '.json';
$now = time();
if (file_exists($file)) {
$data = json_decode(file_get_contents($file), true);
// Usuń stare wpisy poza oknem czasowym
$data['requests'] = array_filter($data['requests'], fn($t) => $t > $now - $window);
} else {
$data = ['requests' => []];
}
if (count($data['requests']) >= $limit) {
return false; // Limit przekroczony
}
$data['requests'][] = $now;
file_put_contents($file, json_encode($data), LOCK_EX);
return true;
}
// Użycie w endpoincie API
$clientIp = $_SERVER['REMOTE_ADDR'];
if (!checkRateLimit($clientIp, limit: 10, window: 60)) {
http_response_code(429);
header('Retry-After: 60');
header('X-RateLimit-Limit: 10');
header('Content-Type: application/json');
echo json_encode(['error' => 'Too Many Requests', 'retry_after' => 60]);
exit;
}
// Normalny request...
header('X-RateLimit-Limit: 10');
echo json_encode(['data' => 'ok']);

Pokaż 429 w praktyce

Otwórz DevTools → Network i pokaż jak wygląda odpowiedź 429 z nagłówkami

Nawiąż do bezpieczeństwa

Rate limiting to pierwsza linia obrony przed brute-force logowania — powiąż z poprzednimi tematami o bezpieczeństwie