Foto av Albert Stoynov via Unsplash
Rate Limiting och API-säkerhet: Skydda utan att straffa
Avancerade rate limiting-mönster med sliding window, adaptiv throttling och DDoS-mitigation. Skydda ditt API utan att försämra upplevelsen för legitima användare.
Rate limiting som säkerhetslager
Rate limiting är inte bara ett prestanda-verktyg — det är en grundläggande säkerhetsmekanism. Utan det kan en angripare brute-forca autentisering, scraipa all data, eller helt enkelt överbelasta din infrastruktur med minimala resurser.
Men aggressiv rate limiting straffar också legitima användare. En mobilapp som gör parallella requests vid appstart, en webhook-konsument som bearbetar en batch, eller en dashboard som laddar flera widgets samtidigt — alla kan oavsiktligt nå gränsen.
Nyckeln är att designa rate limiting som skyddar utan att irritera. Det kräver rätt algoritm, rätt gränser och tydlig kommunikation.
För grunderna i rate limiting-algoritmer, se vår introduktionsartikel om rate limiting och API-throttling.
Sliding window — bättre än fixed window
Fixed window-rate limiting har en svaghet: burst-problemet. Med en gräns på 100 requests per minut kan en klient göra 100 requests vid sekund 59, och ytterligare 100 vid sekund 61 — 200 requests på 2 sekunder.
Sliding window-algoritmen löser detta genom att vikta requests baserat på var i tidsfönstret de befinner sig. Resultatet är jämnare trafikflöde och rättvisare fördelning.
// Sliding window med Redis sorted sets
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL);
async function slidingWindowRateLimit(
identifier: string,
limit: number,
windowMs: number
) {
const now = Date.now();
const windowStart = now - windowMs;
const key = "ratelimit:" + identifier;
const pipeline = redis.pipeline();
pipeline.zremrangebyscore(key, 0, windowStart);
pipeline.zcard(key);
pipeline.zadd(key, now.toString(),
now + "-" + Math.random());
pipeline.pexpire(key, windowMs);
const results = await pipeline.exec();
const count = results![1][1] as number;
if (count >= limit) {
const oldest = await redis.zrange(
key, 0, 0, "WITHSCORES"
);
const retryAfter = oldest.length > 1
? Math.ceil(
(Number(oldest[1]) + windowMs - now) / 1000
)
: Math.ceil(windowMs / 1000);
return {
allowed: false, remaining: 0, retryAfter,
};
}
return {
allowed: true,
remaining: limit - count - 1,
retryAfter: 0,
};
}Adaptiv throttling vid attacker
Statiska rate limits fungerar i normalfallet men räcker inte vid aktiva attacker. Adaptiv throttling ökar skyddet dynamiskt baserat på trafikmönster.
När systemet detekterar onormalt beteende — trafikspikar, många 401-svar, anomala mönster — sänks rate limits automatiskt. När trafiken normaliseras återställs gränserna gradvis.
Kombinera med IP-reputation: kända datacenter-IP:er, Tor exit nodes och VPN-providers kan ha lägre initial trust utan att blockeras helt.
// Adaptiv rate limiting
interface ClientProfile {
requestCount: number;
errorRate: number;
uniqueEndpoints: number;
}
function calculateDynamicLimit(
baseLimit: number,
profile: ClientProfile,
systemLoad: number
): number {
let multiplier = 1.0;
// Hög felfrekvens → sänk limit
if (profile.errorRate > 0.3) multiplier *= 0.5;
else if (profile.errorRate > 0.1) multiplier *= 0.75;
// Scraping-mönster
if (profile.uniqueEndpoints > 50
&& profile.requestCount > 200) {
multiplier *= 0.3;
}
// System under last
if (systemLoad > 0.8) multiplier *= 0.6;
return Math.max(
Math.floor(baseLimit * multiplier), 5
);
}
// Progressiv straffning
async function progressivePenalty(
clientId: string
): Promise<number> {
const violations = await redis.get(
"violations:" + clientId
);
const count = violations ? parseInt(violations) : 0;
if (count === 0) return 0;
if (count <= 3) return 5; // 5s delay
if (count <= 10) return 30; // 30s delay
if (count <= 20) return 300; // 5 min delay
return 3600; // 1h blockering
}Kompletterande API-säkerhet
Rate limiting är ett lager i en djupare säkerhetsstrategi. Komplettera med input-validering (aldrig lita på klientdata), CORS-konfiguration (begränsa vilka domäner som får anropa API:et) och request-signering (HMAC för server-till-server-kommunikation).
Använd WAF (Web Application Firewall) framför ditt API. Cloudflare, AWS WAF eller Fastly kan filtrera bort kända attackmönster innan trafiken når din applikation.
Logga och övervaka alla rate limit-events. Mönster i blockerade requests avslöjar attackvektorer och hjälper dig att finjustera gränserna.
Säkerhetstips: exponera aldrig rate limit-status för oautentiserade requests på känsliga endpoints som /login. Det ger angriparen information om hur många försök som återstår.
För en komplett genomgång av API-autentisering, se vår OAuth 2.0-guide.