Backend

Proteja Suas APIs: Rate Limiting e Segurança com Redis, Express e Next.js

Proteja Suas APIs: Rate Limiting e Segurança com Redis, Express e Next.js

À medida que suas APIs ganham tráfego, aumentar a segurança e controlar a frequência de requisições tornam-se fundamentais. Sem proteção, um endpoint público pode ser alvo de ataques DoS, brute-force em login ou consumos indevidos de recursos. Neste artigo, você vai aprender a:

  1. Contextualizar a necessidade de rate limiting.

  2. Configurar Redis para armazenar contadores de requisições.

  3. Integrar middleware de rate limiting em Express e Next.js.

  4. Adotar boas práticas de segurança em APIs.

  5. Evitar armadilhas comuns no processo.


Por que Rate Limiting é Essencial

Rate limiting é o mecanismo que define quantas requisições um cliente (IP, token ou usuário) pode fazer em um intervalo de tempo. Isso ajuda a:

  • Evitar abusos: previne scraping excessivo ou brute-force.

  • Gerenciar recursos: protege servidores de picos inesperados.

  • Melhorar disponibilidade: mantém a API estável para usuários legítimos.


Implementando Rate Limiting com Redis

1. Instalação das dependências

npm install express redis rate-limit-redis express-rate-limit
# ou, em projetos Next.js:
npm install next redis rate-limit-redis

2. Configurando o cliente Redis

// lib/redis.js
import Redis from 'redis';
 
export const redisClient = Redis.createClient({
  url: process.env.REDIS_URL,
});
redisClient.connect().catch(console.error);

3. Middleware de Rate Limiting no Express

// middleware/rateLimiter.js
import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';
import { redisClient } from '../lib/redis.js';
 
export const limiter = rateLimit({
  store: new RedisStore({
    sendCommand: (...args) => redisClient.sendCommand(args),
  }),
  windowMs: 15 * 60 * 1000, // 15 minutos
  max: 100,                  // 100 requisições por IP
  message: 'Você excedeu o limite de requisições. Tente novamente em breve.',
});
// server.js
import express from 'express';
import { limiter } from './middleware/rateLimiter.js';
 
const app = express();
app.use(limiter);
app.get('/api/data', (req, res) => {
  res.json({ success: true });
});
app.listen(3000, () => console.log('API rodando na porta 3000'));

4. Middleware de Rate Limiting no Next.js

// pages/api/ratelimited.js
import rateLimit from 'next-rate-limit';
import { redisClient } from '../../lib/redis';
 
const limiter = rateLimit({
  store: {
    incr: (key) => redisClient.incr(key),
    ttl: (key, ttl) => redisClient.expire(key, ttl),
    reset: (key) => redisClient.del(key),
  },
  window: 60,  // segundos
  limit: 20,   // 20 requisições
});
 
export default async function handler(req, res) {
  const { success } = await limiter.check(res, 20, 'CACHE_TOKEN');
  if (!success) {
    return res.status(429).json({ error: 'Too many requests' });
  }
  res.status(200).json({ data: 'Conteúdo protegido' });
}

Boas Práticas de Segurança de API

  • Autenticação e autorização sólidas: JWT, OAuth2 ou API Keys com escopos mínimos.

  • HTTPS obrigatório: criptografa dados em trânsito.

  • Validação de entrada: sanitize e valide payloads para evitar injection.

  • Monitoramento e métricas: registre logs de tentativas bloqueadas e padrões de uso.

  • CORS bem configurado: restrinja domínios autorizados.


Armadilhas Comuns e Como Evitá-las

Erro ComumComo Evitar
Contador de requisições não resetadoCertifique-se de usar TTL correto no Redis.
Chave de identificação genéricaUse IP + rota ou token de usuário para granularidade.
Limites muito altos ou baixosAjuste com base no comportamento real dos clientes.
Falta de teste em produçãoSimule picos e testes de carga antes do deploy.

Conclusão

Neste post você viu como integrar Redis com Express e Next.js para implementar rate limiting, além de reforçar a segurança geral da sua API. Agora é com você: teste estas configurações no seu projeto, ajuste os limites conforme sua demanda.