Webhooks Explicados: Payloads Assinados e Estratégias de Retry

Backend2026-10-21TryQuickToolBox

Você criou uma API que envia webhooks para os endpoints dos seus usuários. Mas então surgem os problemas clássicos: como garantir que o payload não foi adulterado? O que acontece quando o endpoint está fora do ar? Como evitar processamento duplicado? Neste artigo, vamos enfrentar esses desafios de frente com payloads assinados e estratégias robustas de retry.

Por que Webhooks Precisam de Assinaturas

Webhooks são callbacks HTTP que notificam outros sistemas sobre eventos. Como são enviados pela internet pública, estão vulneráveis a interceptação e falsificação. Sem uma assinatura, um ator malicioso poderia enviar webhooks falsos para seus usuários, acionando ações indesejadas. Assinar payloads com um segredo compartilhado garante autenticidade e integridade.

Como Funcionam os Payloads Assinados

A abordagem mais comum é HMAC (Hash-based Message Authentication Code) com SHA-256. O remetente e o destinatário compartilham uma chave secreta. O remetente calcula uma assinatura sobre o payload (e às vezes um timestamp) e a inclui em um cabeçalho. O destinatário recalcula a assinatura e a compara com a recebida.

Passo a Passo: Assinando um Payload

  1. Crie o payload: Serialize seus dados de evento para JSON. Garanta formatação consistente (por exemplo, sem espaços extras) porque a assinatura é calculada sobre os bytes exatos.
  2. Adicione um timestamp: Inclua um timestamp Unix no payload ou no cabeçalho para prevenir ataques de replay. O destinatário pode rejeitar requisições mais antigas que alguns minutos.
  3. Calcule o HMAC: Use sua chave secreta para gerar o HMAC-SHA256 da string do payload (ou timestamp + payload).
  4. Anexe a assinatura: Envie-a em um cabeçalho como X-Signature.

Aqui está um exemplo em Python:

import hmac
import hashlib
import json
import time

secret = b'your_shared_secret'
payload = {"event": "user.created", "data": {"id": 123}}
body = json.dumps(payload, separators=(',', ':'))
timestamp = str(int(time.time()))
signed_content = timestamp + '.' + body
signature = hmac.new(secret, signed_content.encode(), hashlib.sha256).hexdigest()

# Send headers: X-Signature: signature, X-Timestamp: timestamp

Verificando a Assinatura

No lado receptor, você deve:

Exemplo de verificação em Node.js:

const crypto = require('crypto');

function verifySignature(req, secret) {
  const signature = req.headers['x-signature'];
  const timestamp = req.headers['x-timestamp'];
  if (!signature || !timestamp) return false;
  if (Date.now() / 1000 - timestamp > 300) return false; // 5 min
  const body = JSON.stringify(req.body);
  const signed = timestamp + '.' + body;
  const expected = crypto.createHmac('sha256', secret).update(signed).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Projetando Estratégias de Retry

Mesmo com assinaturas, webhooks podem falhar devido a problemas de rede, erros de servidor ou timeouts. Uma estratégia robusta de retry garante a entrega sem sobrecarregar o receptor.

Considerações-Chave

Implementando Retries

A maioria dos remetentes de webhooks usa um sistema de filas (por exemplo, Redis, RabbitMQ ou um banco de dados) para agendar retries. Aqui está um fluxo simplificado:

  1. Ao disparar o evento, enfileire um job de webhook com o payload e a URL de destino.
  2. O worker pega o job e tenta a entrega.
  3. Se o status da resposta for 2xx, marque como sucesso.
  4. Se não, agende um retry com backoff exponencial, até o máximo de tentativas.
  5. Após o máximo de tentativas, marque como falho e notifique.

Exemplo de cronograma de retry:

TentativaAtraso
1Imediato
21 minuto
35 minutos
430 minutos
52 horas

Melhores Práticas para Segurança de Webhooks

FAQ

O que é um payload de webhook assinado?

Um payload assinado inclui uma assinatura criptográfica (geralmente HMAC) que permite ao receptor verificar a autenticidade do remetente e que o payload não foi adulterado.

Quantas vezes devo retentar um webhook com falha?

Não há uma resposta única, mas uma abordagem comum é 3–5 retries com backoff exponencial. Considere a criticidade do evento e a capacidade do receptor.

Posso usar JWT para assinaturas de webhook?

Sim, JWT pode ser usado, mas é mais complexo. HMAC é mais simples e suficiente para a maioria dos casos de uso. JWT é útil se você precisar incluir claims ou expiração dentro da própria assinatura.

Pronto para testar seus payloads de webhook? Use nosso JSON Formatter para validar e formatar seus payloads JSON antes de enviar.