Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

API Keys no Node.js

Atualizado em: 6 de outubro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

API keys são credenciais usadas para identificar aplicações, integrações e consumidores de uma API. Elas são simples de operar, mas também fáceis de vazar em repositórios, logs, URLs e frontends. Uma implementação segura precisa gerar chaves fortes, armazenar apenas hashes, limitar escopo, permitir rotação e aplicar rate limiting.

Formato da chave

Use um prefixo identificável e um segredo aleatório:

import crypto from 'node:crypto';

function createApiKey() {
  const id = crypto.randomBytes(8).toString('hex');
  const secret = crypto.randomBytes(32).toString('base64url');
  return {
    id,
    secret,
    value: `cf_live_${id}_${secret}`,
  };
}

O prefixo ajuda scanners e equipes a reconhecer a credencial. Separe ambientes com prefixos como test e live.

Armazene somente hash

function hashApiKey(secret) {
  return crypto.createHash('sha256').update(secret).digest('hex');
}

await apiKeys.insert({
  id,
  secretHash: hashApiKey(secret),
  ownerId,
  scopes: ['orders:read'],
  createdAt: new Date(),
});

Mostre a chave completa apenas uma vez. Depois, exiba somente prefixo e últimos caracteres.

Por que SHA-256 pode ser adequado

API keys bem geradas possuem alta entropia e não são escolhidas por humanos. Um hash rápido é suficiente para comparação e evita o custo de Argon2 em toda requisição. Senhas humanas continuam exigindo Argon2 ou outra função lenta.

Header de autenticação

Authorization: ApiKey cf_live_abcd_...

Também é comum X-API-Key. Não envie a chave em query string, porque URLs aparecem em histórico, analytics, proxies e logs.

Middleware

async function requireApiKey(req, res, next) {
  const header = req.get('authorization') || '';
  const match = header.match(/^ApiKey (.+)$/);

  if (!match) {
    res.status(401).json({ error: 'missing_api_key' });
    return;
  }

  const parsed = parseApiKey(match[1]);
  if (!parsed) {
    res.status(401).json({ error: 'invalid_api_key' });
    return;
  }

  const record = await apiKeys.findById(parsed.id);
  if (!record || record.revokedAt) {
    res.status(401).json({ error: 'invalid_api_key' });
    return;
  }

  const received = Buffer.from(hashApiKey(parsed.secret), 'hex');
  const expected = Buffer.from(record.secretHash, 'hex');

  if (!crypto.timingSafeEqual(received, expected)) {
    res.status(401).json({ error: 'invalid_api_key' });
    return;
  }

  req.apiKey = record;
  next();
}

Valide tamanhos antes de usar timingSafeEqual.

Escopos

Não crie chaves com acesso total por padrão:

function requireScope(scope) {
  return (req, res, next) => {
    if (!req.apiKey.scopes.includes(scope)) {
      res.status(403).json({ error: 'insufficient_scope' });
      return;
    }
    next();
  };
}

Defina escopos estáveis como orders:read, orders:write e webhooks:manage.

Chave por integração

Crie uma chave para cada sistema, ambiente e finalidade. Compartilhar uma chave entre equipes impede rastrear uso e revogar apenas o consumidor comprometido.

Expiração

Chaves podem ter data de expiração, especialmente para acessos temporários. Envie alertas antes do vencimento e permita sobreposição durante rotação.

Rotação

  1. crie uma nova chave;
  2. distribua por canal seguro;
  3. observe uso da nova;
  4. revogue a antiga;
  5. registre o evento.

Evite substituir o segredo no mesmo registro sem período de transição.

Revogação

A revogação deve ser imediata e refletida em caches. Se a validação usa cache local, aplique TTL curto ou mecanismo de invalidação.

Last used

Registre último uso de forma assíncrona e limitada, para não escrever no banco em toda requisição. Esse dado ajuda a remover chaves inativas.

Rate limiting

Limite por key ID e, quando apropriado, por IP e operação. Um atacante com chave roubada não deve consumir capacidade ilimitada.

Quotas

Rate limit controla janelas curtas; quota controla volume diário ou mensal. Não use valores financeiros ou planos vindos de headers do cliente.

Restrição por IP

Allowlist de IP pode complementar, mas não substitui a chave. Redes mudam, proxies compartilhados existem e IP pode não representar identidade confiável.

mTLS

Integrações críticas podem combinar API key com certificado de cliente. Isso reduz o risco de uma chave isolada ser suficiente.

Frontends

Uma chave embutida em JavaScript, aplicativo móvel ou extensão não é segredo. Use-a apenas para identificação pública e aplique limites. Operações privilegiadas precisam de autenticação de usuário ou backend intermediário.

Webhooks

Para webhooks, prefira assinatura HMAC do corpo com timestamp e proteção contra replay. Uma API key estática em header pode ser usada, mas não valida integridade do payload da mesma forma.

Logs

Redija Authorization e X-API-Key:

const logger = pino({
  redact: [
    'req.headers.authorization',
    'req.headers.x-api-key',
  ],
});

Registre key ID, nunca o segredo.

Detecção de vazamento

Use secret scanning em Git, CI e plataformas de código. Prefixos exclusivos facilitam regras. Se uma chave aparecer em repositório público, revogue imediatamente; remover o commit não é suficiente.

Armazenamento pelo cliente

Clientes server-side devem guardar em secret manager ou variável injetada. Não coloque em Dockerfile, imagem, arquivo versionado ou script de build.

Respostas de erro

Use 401 para ausente ou inválida e 403 para escopo insuficiente. Não revele se o ID existia, expirou ou foi revogado.

Auditoria

Registre criação, rotação, revogação, mudança de escopo e uso administrativo. Logs de auditoria devem ser imutáveis e separados dos logs operacionais.

Erros comuns

  • guardar chave em texto puro;
  • enviar em URL;
  • usar chave curta;
  • uma chave para todos os clientes;
  • sem escopos;
  • sem rate limit;
  • não permitir rotação;
  • colocar chave secreta no frontend;
  • registrar headers;
  • cachear revogação por muito tempo.

Testes

Teste chave válida, segredo incorreto, ID inexistente, revogada, expirada, escopo insuficiente, rotação, cache e rate limiting.

Fluxo recomendado

  1. gere alta entropia;
  2. use prefixo e ID;
  3. armazene hash;
  4. mostre uma única vez;
  5. defina escopos mínimos;
  6. limite uso;
  7. permita rotação;
  8. revogue rapidamente;
  9. redija logs;
  10. audite alterações.

Combine API keys com Secret Management, Rate Limiting, Pino, TLS e HTTPS e Idempotency Keys.

Consulte o guia de segurança REST da OWASP e a documentação oficial de crypto no Node.js.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita