Webhooks: Payloads Assinados e Retentativas

Backend2026-09-18TryQuickToolBox

Você acabou de integrar um gateway de pagamento ou um serviço de CI/CD, e agora precisa receber eventos em tempo real. Webhooks são a solução padrão, mas vêm com armadilhas: payloads não autenticados, eventos perdidos e entregas duplicadas. Este artigo explica como os webhooks funcionam, como assinar payloads para evitar adulteração e como implementar retentativas para entrega confiável.

O que são Webhooks?

Um webhook é um callback HTTP definido pelo usuário. Em vez de sua aplicação fazer polling em uma API para obter atualizações, o provedor envia uma requisição HTTP POST para uma URL que você especifica sempre que um evento ocorre. Isso é mais eficiente e permite reações quase em tempo real.

Casos de uso comuns incluem:

Por que assinar payloads de webhook?

Endpoints de webhook são URLs publicamente acessíveis. Sem verificação, qualquer pessoa pode enviar payloads falsos, levando à corrupção de dados ou violações de segurança. Assinar payloads com um segredo compartilhado garante autenticidade e integridade.

A maioria dos provedores usa HMAC (Hash-based Message Authentication Code) com SHA-256. O provedor calcula uma assinatura sobre o corpo bruto da requisição usando uma chave secreta e a inclui em um cabeçalho (ex.: X-Hub-Signature-256). Seu servidor recalcula a assinatura e compara.

Como verificar uma assinatura

Aqui está um guia passo a passo:

  1. Recupere o corpo bruto exatamente como enviado. Não o analise ou modifique antes da verificação.
  2. Extraia a assinatura do cabeçalho.
  3. Calcule a assinatura esperada usando HMAC-SHA256 com seu segredo.
  4. Compare usando uma função de tempo constante para prevenir ataques de temporização.

Exemplo em Node.js:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  const digest = 'sha256=' + hmac.update(payload).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
}

Em Python:

import hmac
import hashlib

def verify_signature(payload, signature, secret):
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f'sha256={expected}', signature)

Sempre use uma comparação de tempo constante para evitar vazamento de informações.

Implementando Retentativas para Confiabilidade

Redes falham, servidores reiniciam e implantações acontecem. Um sistema robusto de webhooks deve tentar novamente entregas falhas. Os provedores geralmente tentam novamente com backoff exponencial, mas você também deve lidar com retentativas no seu lado receptor.

Estratégias de Retentativa

Chaves de Idempotência

Muitos provedores incluem um ID de evento único (ex.: X-Event-ID). Armazene IDs processados em um banco de dados ou cache para pular duplicatas. Por exemplo, use Redis com um TTL para rastrear IDs vistos.

Comparação: Polling vs Webhooks

Aspecto Polling Webhooks
Latência Depende do intervalo Quase em tempo real
Carga do servidor Alta (requisições constantes) Baixa (apenas em eventos)
Complexidade Simples de implementar Requer endpoint, segurança, retentativas
Confiabilidade Perde eventos entre polls Pode perder se o endpoint estiver fora; retentativas ajudam

Melhores Práticas para Consumidores de Webhooks

FAQ

O que é uma assinatura de webhook?

Uma assinatura de webhook é um hash HMAC do payload, criado com um segredo compartilhado. Permite que o receptor verifique que a requisição veio do remetente esperado e não foi adulterada.

Quantas vezes devo tentar novamente um webhook com falha?

Não há um número universal, mas 3–5 retentativas com backoff exponencial é comum. Depois disso, registre o evento em uma fila de mensagens mortas para revisão manual.

Posso usar webhooks sem HTTPS?

Tecnicamente sim, mas é altamente inseguro. Sempre use HTTPS para criptografar payloads e prevenir ataques man-in-the-middle.

Pronto para testar seus endpoints de webhook? Use nosso JSON Formatter para inspecionar e validar payloads rapidamente.