Webhooks Explicados: Payloads Assinados e Estratégias de Retry

Backend2026-10-31TryQuickToolBox

Você acabou de integrar um gateway de pagamento ou um serviço de CI/CD e agora precisa receber eventos em tempo real. Você configurou um endpoint, mas logo se depara com duas questões críticas: como garantir que a requisição realmente veio do serviço? E o que acontece se seu servidor estiver fora do ar quando um evento for disparado? Este artigo responde a ambas explicando payloads assinados e estratégias de retry — a base de webhooks confiáveis.

O que são Webhooks?

Webhooks são callbacks HTTP definidos pelo usuário. Quando um evento ocorre em um sistema de origem (por exemplo, um novo commit, um pagamento bem-sucedido), ele envia uma requisição HTTP POST para uma URL que você fornece. Diferente do polling, webhooks enviam dados quase em tempo real, reduzindo latência e carga no servidor. No entanto, esse modelo de push introduz desafios: verificar autenticidade e lidar com falhas de entrega.

Por que Payloads Assinados Importam

Qualquer um pode enviar uma requisição HTTP para o seu endpoint. Sem verificação, atacantes poderiam forjar eventos, levando a ações não autorizadas. Payloads assinados resolvem isso incluindo uma assinatura criptográfica calculada sobre o corpo da requisição usando um segredo compartilhado. O receptor recalcula a assinatura e compara, garantindo que o payload não foi adulterado e se origina do remetente esperado.

Como Funcionam as Assinaturas HMAC

A maioria dos serviços usa HMAC-SHA256. O remetente cria uma assinatura fazendo o hash do payload com uma chave secreta e a inclui em um cabeçalho (por exemplo, X-Signature). O receptor faz o mesmo e compara usando uma função de tempo constante para prevenir ataques de temporização.

Passo a Passo: Verificando um Payload Assinado

  1. Extraia a assinatura do cabeçalho (por exemplo, X-Signature).
  2. Obtenha o corpo bruto da requisição como string ou buffer — não o analise antes, pois mudanças de formatação quebram a assinatura.
  3. Calcule a assinatura esperada usando HMAC-SHA256 com sua chave secreta.
  4. Compare as assinaturas usando uma função de comparação de tempo constante.
  5. Rejeite a requisição com HTTP 401 se não corresponderem.

Aqui está um exemplo em Node.js usando Express:

const crypto = require('crypto');
const express = require('express');
const app = express();

app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-signature'];
  const secret = process.env.WEBHOOK_SECRET;
  const payload = req.body; // raw buffer

  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event
  const event = JSON.parse(payload);
  // ... handle event
  res.status(200).send('OK');
});

Nota: Sempre use o corpo bruto para verificação. Middlewares que analisam JSON alterarão o payload, causando incompatibilidade de assinatura.

Projetando uma Estratégia de Retry

Mesmo com payloads assinados, problemas de rede ou indisponibilidade do servidor podem causar falhas de entrega. Uma estratégia de retry robusta garante que eventos não sejam perdidos. Considerações principais:

1. Confirme Rapidamente

Responda com um status 2xx assim que validar a assinatura e enfileirar o evento para processamento. Isso evita que o remetente expire e tente novamente desnecessariamente.

2. Idempotência

Retries podem entregar o mesmo evento várias vezes. Use uma chave de idempotência (frequentemente incluída no payload ou cabeçalhos) para deduplicar. Armazene IDs de eventos processados e ignore duplicatas.

3. Backoff Exponencial com Jitter

Se seu endpoint retornar um erro (não-2xx), o remetente deve tentar novamente com atrasos crescentes. O backoff exponencial (por exemplo, 1s, 2s, 4s, 8s) reduz a carga durante indisponibilidades. Adicionar jitter aleatório previne problemas de manada.

Agenda típica de retry:

TentativaAtraso
1Imediato
21 minuto
35 minutos
430 minutos
52 horas

4. Fila de Mensagens Mortas

Após o número máximo de retries, mova o evento para uma fila de mensagens mortas para inspeção manual. Isso evita retries infinitos e perda de dados.

5. Monitoramento e Alertas

Acompanhe taxas de sucesso de entrega, latência e motivos de falha. Configure alertas para picos de falhas para detectar problemas precocemente.

Armadilhas Comuns e Melhores Práticas

FAQ

O que é um payload assinado em webhooks?

Um payload assinado inclui uma assinatura criptográfica (geralmente HMAC) que permite ao receptor verificar a autenticidade e integridade da requisição.

Quantas vezes um webhook deve ser retentado?

Não há um número fixo; práticas comuns variam de 3 a 10 tentativas com backoff exponencial. Depois disso, os eventos geralmente são enviados para uma fila de mensagens mortas.

Posso usar webhooks sem assinaturas?

É possível, mas altamente desencorajado. Sem assinaturas, seu endpoint fica vulnerável a requisições forjadas e violações de dados.

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