Yazılarımız

OfisData

NODE.JS RATE LIMIT UYGULAMAK

Node.js yeşil hex logo solda dönen turnstile kapı sembolü ortada saniye sayacı 5 per min etiketi sağda beyaz fonda

Bir kullanıcı saniyede 1000 kere /api/search endpoint'ine istek atıyor; ya bot ya brute force saldırısı ya da bug. Sunucu boğuluyor; diğer kullanıcılar etkileniyor; veritabanı kilitleniyor. Rate limiting (istek sınırlama) bu senaryoları önleyen temel güvenlik katmanıdır.

Rate limit modern API'lerin standartıdır. GitHub, Twitter, Stripe gibi büyük servisler rate limit kullanır; HTTP sunucu davranışını derinlemesine anlamak için resmi Node.js dokümantasyonu iyi bir başlangıçtır. İyi yapılandırılmış rate limit hem güvenliği hem performansı iyileştirir; kötü yapılandırılmışsa gerçek kullanıcıları bloklayıp UX'i bozar.

Aşağıda rate limiting'in ne olduğunu, Node.js'te nasıl kurulduğunu, hangi stratejilerin hangi durumlarda kullanılacağını anlatıyoruz.

Rate limit nedir?

Belirli bir zaman penceresinde aynı kaynaktan gelen istek sayısını sınırlamak. "IP başına 15 dakikada en fazla 100 istek" gibi.

Sınırı aşan istekler ne olur?

  • 429 Too Many Requests: Standart HTTP yanıt kodu
  • Retry-After header: Ne kadar bekleyeceğini söyler
  • Hata mesajı: "Çok fazla istek, biraz bekleyin"

Neden rate limit?

  • Brute force koruması: Login endpoint'inde 10.000 şifre deneme
  • DDoS koruması: Tek IP'den binlerce istek
  • Scraping önleme: Bot'un içeriği çekmesi
  • Spam koruması: Form gönderimleri kontrol
  • API ücretlendirme: Free tier kullanıcılarına sınır
  • Sunucu kaynak yönetimi: Aşırı yüklenme önleme

express-rate-limit kurulumu

Node.js Express'te en yaygın paket:

npm install express-rate-limit
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 dakika
  max: 100, // IP başına 100 istek
  message: 'Çok fazla istek, biraz bekleyin',
  standardHeaders: true, // RateLimit headers ekle
  legacyHeaders: false   // X-RateLimit eski header'ları kaldır
});

app.use(limiter);

Endpoint bazlı limiter

Tüm uygulamaya tek limit yetersiz. Farklı endpoint'ler farklı sınır gerektirir.

Login (sıkı)

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 dakika
  max: 5, // 15 dakikada 5 yanlış login
  skipSuccessfulRequests: true, // başarılı login'ler sayılmaz
  message: 'Çok fazla başarısız giriş, 15 dakika bekleyin'
});

app.post('/api/login', loginLimiter, loginHandler);

API (orta)

const apiLimiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1 dakika
  max: 60 // dakikada 60 istek
});

app.use('/api/', apiLimiter);

Public içerik (gevşek)

const publicLimiter = rateLimit({
  windowMs: 1 * 60 * 1000,
  max: 200 // dakikada 200 istek
});

app.use('/blog/', publicLimiter);

Authentication sonrası: kullanıcı bazlı

Login olmuş kullanıcılar için IP yerine user ID ile limit:

const userLimiter = rateLimit({
  windowMs: 1 * 60 * 1000,
  max: 100,
  keyGenerator: (req) => req.user?.id || req.ip,
  message: 'Çok fazla istek'
});

app.use('/api/protected', authenticate, userLimiter);

Aynı şirkette 10 kullanıcı aynı IP'den geliyorsa IP bazlı limit tüm şirketi bloklar; user ID bazlı her birine ayrı sınır verir.

VS Code dark theme limiter.js editörü express-rate-limit require windowMs max keyGenerator opsiyonlu konfigürasyon kod bloğu syntax highlight

Algoritma tipleri

Fixed window (sabit pencere)

"15 dakika boyunca 100 istek". Pencere bitince sayaç sıfırlanır.

Avantaj: kolay anlaşılır. Dezavantaj: pencere sınırında "burst" mümkün (son 1 sn ve sonraki 1 sn'de 200 istek).

Sliding window (kaydırmalı pencere)

Son 15 dakikadaki istekleri sayar. Sürekli kaydırılır.

Avantaj: burst engeller. Dezavantaj: daha fazla hesaplama.

Token bucket

Kullanıcının "token bucket"ı var; her istek 1 token harcar. Token'lar yavaş yavaş yenilenir.

Avantaj: kısa süreli burst'lere izin verir. Dezavantaj: konfigürasyon karmaşık.

Distributed rate limiting

Çoklu sunucu varsa in-memory store yetmez. Tüm sunucular ortak bir veri kaynağında sayacı tutmalı.

Redis ile

const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const redis = require('redis');

const client = redis.createClient({
  url: 'redis://localhost:6379'
});

const limiter = rateLimit({
  store: new RedisStore({
    sendCommand: (...args) => client.sendCommand(args)
  }),
  windowMs: 15 * 60 * 1000,
  max: 100
});

app.use(limiter);

Redis hızlı (microsaniye); rate limit overhead'i ihmal edilebilir. Production sistemlerde standart.

Trust proxy ayarı

Express load balancer veya CDN arkasındaysa req.ip yanlış görünür (load balancer IP'sini gösterir). Doğru IP almak için trust proxy:

// Express
app.set('trust proxy', 1); // 1 proxy katmanı

// Veya specific IP
app.set('trust proxy', '192.168.1.1');

Trust proxy aktif olmadan rate limit tüm istekleri aynı IP gibi görür; çalışmaz.

Slow down (rate limit alternatifi)

İstekleri bloklamak yerine yavaşlatmak. express-slow-down paketi:

const slowDown = require('express-slow-down');

const speedLimiter = slowDown({
  windowMs: 15 * 60 * 1000,
  delayAfter: 50, // 50'den sonra yavaşlat
  delayMs: 500 // her sonraki istek 500ms gecikme
});

app.use(speedLimiter);

İlk 50 istek normal; 51. istek 500ms gecikti; 52. 1000ms gecikti. Brute force saldırılarını yavaşlatır ama gerçek kullanıcıları bloklamaz.

Skip ve allowlist

Bazı IP'lerin (kendi ofis, partner) rate limit'i atlatması:

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  skip: (req) => {
    const trustedIPs = ['192.168.1.100', '203.0.113.50'];
    return trustedIPs.includes(req.ip);
  }
});

Otomatize test'lerin de bu listeye eklenmesi gerek; aksi durumda CI/CD test'leri rate limit'e takılır.

Response header'lar

İyi rate limit kullanıcıya kaç istek hakkı kaldığını söyler:

RateLimit-Limit: 100
RateLimit-Remaining: 87
RateLimit-Reset: 1716489600
Retry-After: 120

Bu response header'ları API kullanıcıları için kritik; geliştiriciler ne zaman duracaklarını anlar.

Yaygın senaryolar

API key bazlı limit

SaaS API'ler için. Her API key'in farklı plan kotası var:

const apiKeyLimiter = rateLimit({
  windowMs: 60 * 60 * 1000, // 1 saat
  max: (req) => {
    const apiKey = req.headers['x-api-key'];
    const user = lookupApiKey(apiKey);
    return user.plan === 'pro' ? 10000 : 1000;
  },
  keyGenerator: (req) => req.headers['x-api-key']
});

Endpoint başına dinamik limit

function dynamicLimit(maxRequests) {
  return rateLimit({
    windowMs: 60 * 1000,
    max: maxRequests
  });
}

app.get('/api/search', dynamicLimit(30), searchHandler);
app.post('/api/upload', dynamicLimit(5), uploadHandler);

Test ve monitoring

Rate limit production'da nasıl çalışıyor?

  • Log 429 yanıtlarını: Hangi IP'ler ne sıklıkta limit'e takılıyor
  • Alert kur: Olağandışı 429 artışı uyarı
  • Dashboard: Grafana veya Datadog ile rate limit metrikleri

Yüksek 429 oranı ya saldırı ya da yanlış yapılandırma sinyali; her ikisi de araştırılmalı.

Terminal dark theme apache benchmark ab komutu çıktısı 200 OK ve 429 Too Many Requests yanıt sayıları RateLimit Remaining header satırları

Hatalı Pratikler

  1. Trust proxy ayarı yapmamak. Load balancer arkasında IP yanlış
  2. Tüm endpoint'lere aynı limit. Login ile public içerik aynı sınır olmaz
  3. In-memory store ile multi-server. Her sunucu kendi sayacını tutar; toplam aşılır
  4. Çok sıkı limit. Gerçek kullanıcıları bloklar; UX bozulur
  5. Çok gevşek limit. Saldırıları engelleyemez
  6. 429 mesajı yetersiz. Retry-After header eksik; kullanıcı ne kadar bekleyeceğini bilmez
  7. Test'leri exclude etmemek. CI/CD pipeline limit'e takılır

Disiplinin Kalıcılığı

Rate limiting modern API güvenliğinin temel katmanlarından. Konuya hâkim olmak için Node.js eğitim programı Express, middleware ve API güvenliği konularını birlikte aktarır.

Toparlarsak

Node.js'te rate limiting; brute force, DDoS, scraping ve aşırı yüklenmeye karşı temel koruma katmanıdır. express-rate-limit paketi ile kolay kurulum; endpoint bazlı, user bazlı, API key bazlı farklı stratejiler. Redis ile distributed rate limiting çoklu sunucuda zorunlu. Trust proxy ayarı load balancer arkasında kritik. Çok sıkı limit gerçek kullanıcıları bloklar; çok gevşek saldırıları durduramaz; doğru bant test ve gözlem ile bulunur.

 Vimaj