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:
-
Contextualizar a necessidade de rate limiting.
-
Configurar Redis para armazenar contadores de requisições.
-
Integrar middleware de rate limiting em Express e Next.js.
-
Adotar boas práticas de segurança em APIs.
-
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 Comum | Como Evitar |
---|---|
Contador de requisições não resetado | Certifique-se de usar TTL correto no Redis. |
Chave de identificação genérica | Use IP + rota ou token de usuário para granularidade. |
Limites muito altos ou baixos | Ajuste com base no comportamento real dos clientes. |
Falta de teste em produção | Simule 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.