Webhooks: cargas firmadas y reintentos
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:
- El proveedor y el consumidor comparten una clave secreta (por ejemplo, a través del panel).
- El proveedor calcula
HMAC-SHA256(secret, payload)y lo envía en una cabecera comoX-Signature. - 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
- Retroceso exponencial: Espera más entre cada reintento (por ejemplo, 1s, 2s, 4s, 8s).
- Máximo de intentos: Limita los reintentos (por ejemplo, 5 intentos) para evitar bucles infinitos.
- Cola de mensajes muertos: Tras el máximo de intentos, almacena el evento para inspección manual.
- Idempotencia: Incluye un ID de evento único para que el consumidor pueda ignorar duplicados.
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
- Responde con 2xx rápidamente; procesa de forma asíncrona si es necesario.
- Valida la firma antes de cualquier procesamiento.
- Usa claves de idempotencia para manejar entregas duplicadas.
- Registra todos los webhooks entrantes para depuración.
- Monitoriza fallos y alerta ante errores repetidos.
Comparación: polling vs webhooks
| Aspecto | Polling | Webhooks |
|---|---|---|
| Latencia | Alta (basada en intervalo) | Baja (tiempo real) |
| Carga del servidor | Solicitudes constantes | Solo en eventos |
| Complejidad | Simple | Requiere reintentos/seguridad |
| Caso de uso | Escala pequeña, actualizaciones poco frecuentes | Integraciones 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.