PureTools

Rate Limiting: Proteja Sua API de Abuso

PureTools Team· 7 min de leitura
Rate Limiting: Proteja Sua API de Abuso

Rate Limiting: A Primeira Linha de Defesa da Sua API

Sem rate limiting, um único usuário (ou bot) pode sobrecarregar sua API com milhares de requests por segundo. Rate limiting limita o número de requisições que um cliente pode fazer em uma janela de tempo.

Algoritmos Comuns

AlgoritmoComo FuncionaPrósContras
Fixed WindowConta requests por janela fixa de tempoSimplesBurst nas bordas da janela
Sliding WindowConta requests em janela deslizanteDistribuição suaveMais memória
Token BucketTokens reabastecem em taxa fixa; cada request custa um tokenPermite bursts controladosLigeiramente complexo

Headers de Resposta

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1682345700

HTTP/1.1 429 Too Many Requests
Retry-After: 30
{ "error": "Rate limit excedido" }

Express.js com Redis

import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';

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

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

// Limites diferentes por endpoint
const strictLimiter = rateLimit({ windowMs: 60000, max: 10 });
app.post('/api/auth/login', strictLimiter, loginHandler);

Sliding Window DIY com Redis

async function checkRateLimit(userId, limit = 100, window = 60) {
  const key = `rate:${userId}`;
  const now = Date.now();
  const windowStart = now - window * 1000;

  const pipeline = redis.pipeline();
  pipeline.zremrangebyscore(key, 0, windowStart);
  pipeline.zadd(key, now, `${now}:${Math.random()}`);
  pipeline.zcard(key);
  pipeline.expire(key, window);

  const results = await pipeline.exec();
  const count = results[2][1];

  return { allowed: count <= limit, remaining: Math.max(0, limit - count) };
}

Boas Práticas

  • Retorne status 429 com header Retry-After
  • Inclua headers de rate limit em toda resposta
  • Use limites diferentes por endpoint (login vs leitura)
  • Registre rate limit hits para detecção de abuso