Rate Limiting Nedir?
Rate limiting, belirli bir zaman diliminde bir API endpoint'ine yapılabilecek istek sayısını sınırlama mekanizmasıdır. Mobil uygulamanızın backend'ini korumak için en temel güvenlik katmanlarından biridir.
Neden gerekli?
- DDoS saldırılarından korunma
- Brute force login denemelerini engelleme
- API maliyetlerini kontrol altında tutma
- Fair usage sağlama
- Sunucu stabilitesini koruma
Rate Limiting Algoritmaları
Fixed Window
En basit yaklaşım. Belirli bir zaman penceresi içinde izin verilen istek sayısını sayar.
- Avantaj: Implementasyonu kolay, bellek kullanımı düşük
- Dezavantaj: Pencere sınırında burst problemi
Sliding Window
Fixed window'un geliştirilmiş hali. Mevcut ve önceki pencerenin ağırlıklı ortalamasını kullanır.
- Avantaj: Burst problemini büyük ölçüde çözer
- Dezavantaj: Biraz daha fazla hesaplama gerektirir
Token Bucket
Bir kovaya belirli hızla token eklenir, her istek bir token harcar. Kova boşalırsa istek reddedilir.
- Avantaj: Kısa süreli burst'lere izin verir ama uzun vadede limiti korur
- Dezavantaj: Implementasyonu biraz daha karmaşık
Çoğu production sistemi sliding window veya token bucket kullanır.
Backend Implementasyonu
Fastify (@fastify/rate-limit)
- Global veya route bazında limit tanımlanabilir
- Redis backend ile distributed rate limiting
- keyGenerator ile IP, user ID veya API key bazlı sınırlama
Express (express-rate-limit)
- windowMs ve max parametreleri ile temel konfigürasyon
- rate-limit-redis ile Redis backend desteği
- Trust proxy ayarını doğru yapın (load balancer arkasındaysanız)
Redis Tabanlı Distributed Limiting
Birden fazla sunucu instance'ınız varsa in-memory rate limiting yeterli olmaz. Redis ile tüm instance'lar aynı sayacı paylaşır.
Per-User vs Per-IP vs Per-Endpoint
| Strateji | Kullanım Alanı | Dikkat Edilecekler |
|---|---|---|
| Per-IP | Genel koruma, login | NAT arkasında aynı IP paylaşımı |
| Per-User | Authenticated endpoint'ler | Token bazlı sayım |
| Per-Endpoint | Farklı endpoint'lere farklı limit | /login sıkı, /feed gevşek |
| Per-API Key | 3rd party entegrasyonlar | Plan bazlı limit |
En iyi yaklaşım bunları birleştirmektir. Orneğin: login'de per-IP 5/dk + per-user 10/dk.
429 Too Many Requests Handling
Backend tarafı:
- Retry-After header'ı ekleyin
- X-RateLimit-Limit ve X-RateLimit-Remaining header'ları gönderin
Client tarafı:
- 429 aldığında Retry-After header'ına göre bekleyin
- Exponential backoff uygulayın
- Kullanıcıya anlamlı mesaj gösterin
- Maksimum deneme sayısı belirleyin
API Key Authentication
- API key'i header'da gönderin (X-API-Key), URL parametresi olarak asla
- Key'leri hashleyerek saklayın
- Key rotation mekanizması kurun
- Farklı key'lere farklı scope atayın
CORS Yapılandırması
Mobil native uygulamalarda CORS uygulanmaz ama API'niz hem web hem mobil'e hizmet veriyorsa doğru yapılandırma şarttır.
- origin'i * yerine spesifik domain'lere sınırlayın
- credentials: true kullanıyorsanız wildcard origin kullanamazsınız
- Preflight cache süresi ayarlayın
- Sadece gerekli HTTP method'larına izin verin
Input Validation ve Sanitization
Gelen her veriyi güvenilmez kabul edin.
- Request body'yi schema ile validate edin (Zod, Joi, Yup)
- SQL injection'a karşı parametrize sorgular kullanın
- XSS'e karşı HTML tag'lerini sanitize edin
- Dosya yükleme'de tip ve boyut kontrolü yapın
Security Headers
Helmet.js (Express) veya @fastify/helmet (Fastify) ile otomatik eklenebilir:
- Strict-Transport-Security: HTTPS zorunluluğu
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- Content-Security-Policy: kaynak kısıtlamaları
API güvenliği katmanlı bir yaklaşım gerektirir. Rate limiting, authentication, input validation ve security headers birlikte uygulandığında etkili bir savunma hattı oluşturur.