Webhooks Explicados: Payloads Assinados e Lógica de Retentativa

Backend2026-10-28TryQuickToolBox

Você construiu uma API e agora precisa notificar outros serviços quando eventos acontecem. O polling é ineficiente, então você recorre a webhooks. Mas logo descobre que webhooks podem falhar, ser falsificados ou causar processamento duplicado. Este artigo explica como proteger webhooks com payloads assinados e implementar uma lógica de retentativa robusta.

O que são Webhooks?

Webhooks são callbacks HTTP definidos pelo usuário. Quando um evento ocorre no seu sistema (por exemplo, um pagamento é bem-sucedido), você envia uma requisição HTTP POST para uma URL fornecida pelo assinante. O payload normalmente contém dados do evento em formato JSON ou form.

Webhooks permitem comunicação em tempo real entre serviços sem polling constante. Eles são amplamente usados por gateways de pagamento, ferramentas de CI/CD e plataformas SaaS.

Por que proteger Webhooks?

Sem segurança, qualquer pessoa que conheça a URL do webhook pode enviar requisições falsas, levando à corrupção de dados ou fraude. Além disso, atacantes podem reenviar requisições antigas. Assinar payloads com um segredo compartilhado garante autenticidade e integridade.

Assinando Payloads com HMAC

HMAC (Hash-based Message Authentication Code) é um método comum para assinar webhooks. O remetente e o destinatário compartilham uma chave secreta. O remetente calcula um HMAC do payload usando o segredo e o inclui em um cabeçalho (por exemplo, X-Signature). O destinatário recalcula o HMAC e compara.

Passo a Passo: Enviando um Webhook Assinado

  1. Crie o payload (JSON).
  2. Calcule o HMAC-SHA256 do payload usando o segredo.
  3. Inclua o digest hexadecimal em um cabeçalho, por exemplo, X-Signature: sha256=....
  4. Envie a requisição POST.
// Exemplo em Node.js usando crypto
const crypto = require('crypto');
const secret = 'your_shared_secret';
const payload = JSON.stringify({ event: 'payment.success', amount: 100 });
const signature = crypto.createHmac('sha256', secret).update(payload).digest('hex');
// Envie POST com o cabeçalho X-Signature: sha256=signature

Verificando a Assinatura

No lado do destinatário, extraia o cabeçalho de assinatura, calcule o HMAC do corpo bruto da requisição e compare usando uma comparação de tempo constante para prevenir ataques de temporização.

// Exemplo com Express.js
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-signature'];
  const computed = crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(computed))) {
    return res.status(401).send('Assinatura inválida');
  }
  // Processe o payload
  res.status(200).send('OK');
});

Nota: Certifique-se de usar o corpo bruto, não o JSON parseado, pois a análise pode alterar o payload.

Prevenindo Ataques de Repetição

Inclua um timestamp no payload assinado e rejeite requisições mais antigas que alguns minutos. Além disso, inclua um ID de evento único e armazene IDs processados para evitar duplicatas.

Lógica de Retentativa para Entrega Confiável

Endpoints de webhook podem estar fora do ar ou lentos. Implemente retentativas com backoff exponencial e jitter. Defina um número máximo de retentativas (por exemplo, 5) e um timeout para cada requisição.

Estratégia de Retentativa

Exemplo de cronograma de retentativa: 1ª retentativa após 5s, 2ª após 30s, 3ª após 2min, 4ª após 10min, 5ª após 1h.

Lidando com Falhas

Se todas as retentativas falharem, registre a falha e notifique o assinante (por exemplo, via e-mail ou dashboard). Forneça uma maneira de reenviar webhooks manualmente.

Comparação: Payloads Assinados vs. Basic Auth

Método Segurança Complexidade Proteção contra Repetição
Payload Assinado com HMAC Alta Moderada Sim (com timestamp)
Basic Auth Baixa Baixa Não
API Key no Cabeçalho Média Baixa Não

Melhores Práticas

FAQ

Como verifico uma assinatura de webhook?

Calcule o HMAC do corpo bruto da requisição usando seu segredo e compare com o cabeçalho de assinatura usando uma comparação de tempo constante.

O que devo fazer se um webhook falhar?

Implemente retentativas com backoff exponencial e jitter. Se todas as retentativas falharem, registre a falha e forneça uma opção de reenvio manual.

Posso usar webhooks sem assinatura?

Não é recomendado. Sem assinatura, você não pode verificar o remetente, tornando seu sistema vulnerável a falsificação e ataques de repetição.

Ao testar payloads de webhook, você pode precisar inspecionar respostas JSON. Use nosso JSON Formatter para formatar e validar dados JSON rapidamente.