Webhooks: cargas firmadas y reintentos

Backend2026-10-07TryQuickToolBox

Por qué los webhooks son potentes y frágiles a la vez

Los webhooks impulsan integraciones en tiempo real: notificaciones de pago, disparadores de CI/CD, mensajes de chat. Pero conllevan dos grandes desafíos: seguridad (¿cómo sabes que la solicitud proviene del remitente esperado?) y fiabilidad (¿qué pasa si el receptor está caído?). Este artículo te muestra cómo abordar ambos con cargas firmadas y estrategias de reintentos.

¿Qué es un webhook?

Un webhook es una solicitud HTTP POST que un proveedor envía a un consumidor cuando ocurre un evento. A diferencia del polling, los webhooks envían datos casi en tiempo real, reduciendo la latencia y la carga del servidor. El proveedor debe garantizar que la solicitud sea auténtica; el consumidor debe procesarla de forma fiable.

Proteger webhooks con cargas firmadas

Una carga firmada utiliza una clave secreta para crear una firma criptográfica (normalmente HMAC-SHA256) del cuerpo de la solicitud. El receptor recalcula la firma y la compara con la que viene en la cabecera. Si coinciden, la carga es auténtica y no ha sido manipulada.

Cómo generar y verificar firmas

Este es un flujo típico:

  1. El proveedor y el consumidor comparten una clave secreta (por ejemplo, a través del panel).
  2. El proveedor calcula HMAC-SHA256(secret, payload) y lo envía en una cabecera como X-Signature.
  3. El consumidor lee el cuerpo sin procesar, calcula el mismo HMAC y lo compara usando una función de tiempo constante.

Ejemplo en Node.js:

const crypto = require('crypto');

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

Usa siempre una comparación de tiempo constante para prevenir ataques de temporización. Nunca analices el cuerpo antes de la verificación: utiliza middleware de cuerpo sin procesar.

Implementar reintentos para una entrega fiable

Incluso con firmas, los fallos de red o las interrupciones temporales pueden hacer que falle la entrega del webhook. Un mecanismo de reintento robusto garantiza la entrega eventual.

Estrategias de reintento

Ejemplo de lógica de reintento en Python:

import time
import requests

def send_webhook(url, payload, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=payload, timeout=5)
            if response.status_code == 200:
                return True
        except requests.RequestException:
            pass
        time.sleep(2 ** attempt)  # exponential backoff
    return False

Buenas prácticas para consumidores de webhooks

Comparación: polling vs webhooks

AspectoPollingWebhooks
LatenciaAlta (basada en intervalo)Baja (tiempo real)
Carga del servidorSolicitudes constantesSolo en eventos
ComplejidadSimpleRequiere reintentos/seguridad
Caso de usoEscala pequeña, actualizaciones poco frecuentesIntegraciones en tiempo real

Preguntas frecuentes

¿Qué es una carga de webhook firmada?

Una carga firmada incluye una firma criptográfica (por ejemplo, HMAC) que permite al receptor verificar que la solicitud proviene de una fuente confiable y no ha sido manipulada.

¿Cuántas veces debo reintentar un webhook fallido?

No hay un número universal, pero 3–5 intentos con retroceso exponencial es lo común. Después de eso, registra el evento para revisión manual.

¿Puedo usar JWT en lugar de HMAC para las firmas de webhooks?

Sí, algunos proveedores usan JWT. El principio es el mismo: verifica la firma y las claims del token antes de confiar en la carga.

¿Necesitas inspeccionar cargas o registros de webhooks? Prueba nuestro JSON Formatter para formatear y validar cargas JSON rápidamente.