Webhooks

Webhooks

Recibe notificaciones HTTP en tiempo real cuando ocurren eventos de autenticación en tu proyecto. Sincroniza usuarios con tu base de datos, envía correos de bienvenida o activa flujos de trabajo cuando los usuarios se registran, inician sesión o son bloqueados.

¿Qué son los Webhooks?

Un webhook es un callback HTTP que tu servidor registra para recibir notificaciones de eventos en tiempo real. En lugar de consultar Authon para verificar si un usuario fue eliminado o bloqueado, Authon envía proactivamente una solicitud POST a tu URL en el momento en que ocurre el evento.

text
Usuario eliminado en el panel de Authon
  → Authon envía POST /webhooks/authon
  → Tu servidor recibe el evento y elimina al usuario de tu base de datos

Cómo funcionan los Webhooks

Cuando ocurre un evento en tu proyecto de Authon, la API envía una solicitud POST a tu endpoint registrado con un payload JSON. Cada solicitud incluye un encabezado X-Authon-Signature con el prefijo v1= — una firma HMAC-SHA256 calculada sobre timestamp.body usando tu secreto de firma del webhook. Siempre verifica esta firma antes de procesar el evento.

1
Ocurre un evento en Authon (ej. un usuario se registra)
2
Authon firma el payload con HMAC-SHA256 usando tu secreto de webhook
3
Authon envía una solicitud POST a la URL de tu endpoint
4
Tu servidor verifica la firma y procesa el evento
5
Tu servidor responde con 2xx para confirmar la recepción

Configurar un Webhook

  1. 1
    Navega a Panel → Webhooks → Agregar Webhook
  2. 2
    Ingresa la URL de tu endpoint — debe ser accesible públicamente mediante HTTPS
  3. 3
    Selecciona los eventos que deseas recibir
  4. 4
    Copia el secreto de firma — se muestra solo una vez, guárdalo de forma segura
  5. 5
    Configura AUTHON_WEBHOOK_SECRET en el entorno de tu servidor

Tipos de eventos

EventoDisparador
user.createdUn nuevo usuario completa el registro
user.updatedEl perfil de un usuario es actualizado
user.deletedUna cuenta de usuario es eliminada permanentemente
user.signinUn usuario inicia sesión (correo u OAuth)
user.signoutUn usuario cierra sesión
user.bannedUn administrador bloquea a un usuario
user.unbannedSe levanta el bloqueo de un usuario
session.createdSe crea una nueva sesión (inicio de sesión, actualización de token)
session.revokedSe revoca una sesión (cierre de sesión, revocación por admin)

Formato del payload

Cada payload de webhook es un objeto JSON con una estructura de nivel superior consistente. El campo data contiene detalles específicos del evento.

json
{
  "event": "user.created",
  "data": {
    "user": {
      "id": "usr_abc123",
      "email": "user@example.com",
      "displayName": "Jane Doe",
      "emailVerified": false,
      "isBanned": false,
      "publicMetadata": null,
      "createdAt": "2026-01-15T10:30:00.000Z",
      "updatedAt": "2026-01-15T10:30:00.000Z"
    }
  },
  "timestamp": "2026-01-15T10:30:00.000Z"
}

Para eventossession.*, el campo datatambién incluye un objeto sessioncon id, ipAddress y userAgent.

Verificación de firma

Cada solicitud de webhook contiene un encabezado X-Authon-Signature con el formato v1=<hex_digest>. La firma se calcula como HMAC-SHA256 sobre timestamp.rawBody usando tu secreto de webhook. Compara el resultado con igualdad de tiempo constante.

EncabezadoFormatoDescripción
X-Authon-Signaturev1={hmac_sha256}Firma HMAC-SHA256 para verificar el origen de la solicitud
X-Authon-TimestampISO 8601Marca de tiempo ISO 8601 de cuándo se envió el evento
X-Authon-Eventuser.createdEl tipo de evento (ej. user.created, session.revoked)
Usa siempre el buffer del cuerpo sin procesar para la verificación, no una cadena JSON parseada. El middleware json() de Express re-serializa el cuerpo, lo que puede alterar los espacios en blanco y romper la firma.

Ejemplo con Node.js

routes/webhooks.ts
import { createHmac, timingSafeEqual } from "crypto";
import express from "express";

const router = express.Router();

function verifySignature(
  rawBody: Buffer,
  signature: string,
  secret: string,
  timestamp: string,
): boolean {
  const payload = `${timestamp}.${rawBody.toString()}`;
  const expected = createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  const actual = signature.replace("v1=", "");

  const expectedBuf = Buffer.from(expected, "hex");
  const actualBuf = Buffer.from(actual, "hex");

  return (
    expectedBuf.length === actualBuf.length &&
    timingSafeEqual(expectedBuf, actualBuf)
  );
}

router.post(
  "/webhooks/authon",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-authon-signature"] as string;
    const timestamp = req.headers["x-authon-timestamp"] as string; // ISO 8601
    const eventType = req.headers["x-authon-event"] as string;
    const webhookSecret = process.env.AUTHON_WEBHOOK_SECRET!;

    if (!verifySignature(req.body, signature, webhookSecret, timestamp)) {
      return res.status(401).json({ error: "Invalid signature" });
    }

    const { event, data } = JSON.parse(req.body.toString());

    switch (eventType) {
      case "user.created":
        // Sync new user to your database
        break;
      case "user.deleted":
        // Remove user from your database
        break;
      case "user.updated":
        // Update user data
        break;
      case "user.banned":
        // Revoke app-level access
        break;
    }

    res.status(200).json({ received: true });
  }
);

export default router;

Usando el SDK

El SDK@authon/node proporciona un helper de verificación integrado que maneja la comparación de tiempo constante por ti:

ts
import { AuthonBackend } from "@authon/node";

const authon = new AuthonBackend(process.env.AUTHON_SECRET_KEY!);

router.post(
  "/webhooks/authon",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-authon-signature"] as string;
    const timestamp = req.headers["x-authon-timestamp"] as string;

    let event: Record<string, unknown>;
    try {
      event = authon.webhooks.verify(
        req.body,
        signature,
        timestamp,
        process.env.AUTHON_WEBHOOK_SECRET!,
      );
    } catch {
      return res.status(401).json({ error: "Invalid signature" });
    }

    console.log("Verified event:", event.event);
    res.json({ received: true });
  }
);

Política de reintentos

Si tu endpoint retorna un código de estado diferente a 2xx o no responde dentro de 10 segundos, Authon reintenta la entrega con retroceso exponencial. Máximo 3 intentos en total.

IntentoRetrasoTiempo acumulado
Inicial0s
1er reintento1 second~1s
2do reintento2 seconds~3s

Casos de uso

Sincronizar usuarios con tu base de datos
Mantén la tabla de usuarios de tu app sincronizada con Authon. Escucha user.created, user.updated y user.deleted para reflejar los cambios automáticamente.
Enviar correos de bienvenida
Activa un correo de bienvenida o una secuencia de incorporación cuando se dispara user.created. Usa el correo del usuario y el nombre de pantalla del payload del evento.
Aplicar bloqueos en tiempo real
Cuando se dispara user.banned, revoca inmediatamente los tokens de acceso de nivel de app o las entradas de caché para que el usuario no pueda seguir usando tu servicio.

Buenas prácticas

Siempre verifica la firma
Nunca omitas la verificación de firma. Cualquiera puede hacer POST a tu endpoint — la verificación prueba que la solicitud provino de Authon.
Usa el parsing del cuerpo sin procesar
La verificación de firma requiere los bytes exactos sin procesar del cuerpo de la solicitud. Evita el middleware JSON en las rutas de webhook.
Responde rápido, procesa de forma asíncrona
Retorna 200 de inmediato y procesa el evento de forma asíncrona. Authon reintentará si tu endpoint tarda más de 10 segundos.
Haz los handlers idempotentes
Puedes recibir el mismo evento más de una vez debido a los reintentos. Usa la marca de tiempo del evento para deduplicar — guarda los eventos procesados en tu base de datos.
Rota los secretos periódicamente
Genera un nuevo secreto de firma desde el Panel cada 90 días. Actualiza AUTHON_WEBHOOK_SECRET en tu despliegue sin tiempo de inactividad.
Authon — Plataforma universal de autenticación