Aprenda / Redes e Internet

IntermediárioAula 14 de 1615 min0% da trilha

Rate limiting e proteção contra abuso

Sem limite de requisição, um único cliente mal-intencionado (ou um bug num script) consegue derrubar a API pra todo mundo.

Praticamente toda API pública limita quantas requisições um mesmo cliente pode fazer num intervalo de tempo. Não é paranoia: sem limite, um script com bug rodando em loop, um scraper agressivo, ou uma tentativa de força bruta contra login conseguem consumir toda a capacidade do servidor — prejudicando todos os outros usuários legítimos ao mesmo tempo.

Token bucket — a ideia mais comum por trás do rate limit

Um jeito simples (e muito usado) de implementar limite de requisição é o token bucket: existe um "balde" com capacidade fixa de tokens; cada requisição consome um token; o balde recarrega a uma taxa constante. Sem token disponível, a requisição é recusada — mas o balde permite uma rajada momentânea de requisições (até a capacidade do balde), não só uma taxa média rígida.

token bucket, em pseudocódigo
capacidade = 10           // até 10 requisições em rajada
tokens = 10
taxa_recarga = 1/segundo  // 1 token novo a cada segundo

a cada requisição recebida:
  se tokens > 0:
    tokens = tokens - 1
    processa a requisição normalmente
  senão:
    responde 429 Too Many Requests

429 Too Many Requests — o status pensado pra isso

resposta de rate limit
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{"error": "Limite de requisições excedido. Tente novamente em 30 segundos."}

O header Retry-After diz explicitamente ao cliente quanto tempo esperar antes de tentar de novo — evitando que ele fique tentando imediatamente em loop, o que só pioraria a situação.

Onde aplicar o limite

nginx aplicando limite por IP
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;

server {
  location /api/ {
    limit_req zone=api burst=10 nodelay;
    proxy_pass http://backend;
  }
}

O limite normalmente é aplicado por cliente (IP, chave de API, ou usuário autenticado), não de forma global — senão um único cliente abusivo derrubaria a cota de todo mundo. Pode viver no proxy reverso (como no exemplo acima), na própria aplicação, ou num serviço dedicado com contador compartilhado (Redis costuma ser a escolha, já que vários servidores atrás de um load balancer precisam enxergar a mesma contagem).

Exercício

Por que um endpoint de login geralmente precisa de um limite de requisição bem mais rígido do que um endpoint público de leitura, tipo listar produtos de uma loja?

Quiz rápido

Qual a ideia central do algoritmo de token bucket para rate limiting?
O que o status 429 Too Many Requests comunica ao cliente?