Rate Limiting em Node.js: Guia Completo para Proteção de API e Gerenciamento de Carga

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Rate Limiting em Node.js: Protegendo a API contra Sobrecargas e Ataques

\n\n

Rate limiting (limitação de taxa de requisições) é um mecanismo criticamente importante para qualquer aplicação web em Node.js. Ele permite controlar o número de requisições que um cliente pode enviar ao servidor em um determinado período de tempo. Sem rate limiting, sua API fica vulnerável a ataques DDoS, sobrecargas acidentais e consumo excessivo de recursos.

\n\n

Por que o Rate Limiting é necessário?

\n
    \n
  • Proteção contra brute force: Previne múltiplas tentativas de login no sistema.
  • \n
  • Prevenção de DDoS: Limita o impacto de ataques de negação de serviço.
  • \n
  • Distribuição justa de recursos: Garante acesso igual para todos os usuários.
  • \n
  • Economia de custos: Reduz a carga nos servidores e bancos de dados.
  • \n
  • Conformidade com SLA: Cumprimento de acordos de nível de serviço.
  • \n
\n\n

Principais Algoritmos de Rate Limiting

\n

Existem várias abordagens para implementar a limitação de taxa. Vejamos as mais populares:

\n\n

1. Sliding Window (Janela Deslizante)

\n

O algoritmo mais comum. As requisições são agrupadas em janelas de tempo (por exemplo, 1 minuto). Se o número de requisições exceder o limite, as próximas requisições são rejeitadas até o início de uma nova janela.

\n\n

2. Token Bucket (Balde de Tokens)

\n

Um "balde" virtual contém tokens. Cada requisição consome um token. Os tokens são reabastecidos a uma taxa fixa. Se o balde estiver vazio, a requisição é rejeitada.

\n\n

3. Leaky Bucket (Balde Furado)

\n

As requisições entram em uma fila e são processadas a uma taxa constante. Se a fila transbordar, as requisições são descartadas.

\n\n

Bibliotecas para Rate Limiting em Node.js

\n\n

1. express-rate-limit

\n

A biblioteca mais popular para Express.js. Simples de usar e configurável.

\n\n
const rateLimit = require('express-rate-limit');\n\n// Criando middleware para limitar requisições\nconst limiter = rateLimit({\n  windowMs: 15 * 60 * 1000, // 15 minutos\n  max: 100, // máximo de 100 requisições por janela\n  message: 'Muitas requisições, tente novamente mais tarde.',\n  standardHeaders: true, // Retorna cabeçalhos RateLimit-*\n  legacyHeaders: false, // Desativa cabeçalhos X-RateLimit-*\n});\n\n// Aplicando a todas as rotas\napp.use(limiter);\n\n// Ou apenas a uma rota específica\napp.use('/api/login', limiter);\n
\n\n

2. bottleneck

\n

Biblioteca universal que funciona com qualquer operação assíncrona. Suporta os algoritmos Token Bucket e Leaky Bucket.

\n\n
const Bottleneck = require('bottleneck');\n\n// Criando limitador: 5 requisições por segundo\nconst limiter = new Bottleneck({\n  minTime: 200, // 200 ms entre requisições\n  maxConcurrent: 5, // máximo de 5 requisições simultâneas\n  reservoir: 100, // quantidade inicial de tokens\n  reservoirRefreshAmount: 100,\n  reservoirRefreshInterval: 60 * 1000, // reabastecimento a cada minuto\n});\n\n// Encapsulando a função no limitador\nasync function fetchData(url) {\n  const response = await fetch(url);\n  return response.json();\n}\n\nconst limitedFetch = limiter.wrap(fetchData);\n\n// Uso\nconst data = await limitedFetch('https://api.example.com/data');\n
\n\n

3. rate-limiter-flexible

\n

Biblioteca flexível com suporte a Redis, MongoDB, Memcached e outros armazenamentos. Ideal para sistemas distribuídos.

\n\n
const { RateLimiterRedis } = require('rate-limiter-flexible');\nconst Redis = require('ioredis');\n\nconst redisClient = new Redis();\n\nconst rateLimiter = new RateLimiterRedis({\n  storeClient: redisClient,\n  keyPrefix: 'middleware',\n  points: 10, // 10 requisições\n  duration: 1, // por 1 segundo\n});\n\napp.use(async (req, res, next) => {\n  try {\n    await rateLimiter.consume(req.ip);\n    next();\n  } catch (rejRes) {\n    res.status(429).send('Muitas requisições');\n  }\n});\n
                
    
    

Recommendations