Webhooks
Receba notificações HTTP em tempo real quando eventos de autenticação ocorrerem no seu projeto. Sincronize usuários com seu banco de dados, envie e-mails de boas-vindas ou acione fluxos de trabalho sempre que usuários se cadastrarem, entrarem ou forem banidos.
O que são Webhooks?
Um webhook é um callback HTTP que seu servidor registra para receber notificações de eventos em tempo real. Em vez de consultar o Authon para verificar se um usuário foi excluído ou banido, o Authon envia proativamente uma requisição POST para sua URL no momento em que o evento ocorre.
Usuário excluído no dashboard do Authon
→ Authon envia POST /webhooks/authon
→ Seu servidor recebe o evento e remove o usuário do seu DBComo os Webhooks Funcionam
Quando um evento ocorre no seu projeto Authon, a API envia uma requisição POST para o seu endpoint registrado com um payload JSON. Cada requisição inclui um cabeçalho X-Authon-Signature com um prefixo v1= — uma assinatura HMAC-SHA256 calculada sobre timestamp.body usando o seu segredo de assinatura de webhook. Sempre verifique esta assinatura antes de processar o evento.
Configurando um Webhook
- 1Acesse Dashboard → Webhooks → Adicionar Webhook
- 2Informe a URL do seu endpoint — deve ser acessível publicamente via HTTPS
- 3Selecione os eventos que deseja receber
- 4Copie o segredo de assinatura — exibido apenas uma vez, armazene-o com segurança
- 5Defina AUTHON_WEBHOOK_SECRET no ambiente do seu servidor
Tipos de Eventos
| Evento | Gatilho |
|---|---|
| user.created | Um novo usuário conclui o cadastro |
| user.updated | O perfil de um usuário é atualizado |
| user.deleted | Uma conta de usuário é excluída permanentemente |
| user.signin | Um usuário entra (e-mail ou OAuth) |
| user.signout | Um usuário sai |
| user.banned | Um usuário é banido por um administrador |
| user.unbanned | Um usuário banido é restaurado |
| session.created | Uma nova sessão é criada (login, atualização de token) |
| session.revoked | Uma sessão é revogada (logout, revogação pelo administrador) |
Formato do Payload
Todo payload de webhook é um objeto JSON com uma estrutura consistente no nível superior. O campo data contém detalhes específicos do evento.
{
"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.*, o campo datatambém inclui um objeto sessioncom id, ipAddress e userAgent.
Verificação de Assinatura
Cada requisição de webhook contém um cabeçalho X-Authon-Signature com o formato v1=<hex_digest>. A assinatura é calculada como HMAC-SHA256 sobre timestamp.rawBody usando seu segredo de webhook. Compare o resultado com igualdade de tempo constante.
| Cabeçalho | Formato | Descrição |
|---|---|---|
| X-Authon-Signature | v1={hmac_sha256} | Assinatura HMAC-SHA256 para verificar a origem da requisição |
| X-Authon-Timestamp | ISO 8601 | Timestamp ISO 8601 de quando o evento foi enviado |
| X-Authon-Event | user.created | O tipo de evento (ex.: user.created, session.revoked) |
json() do Express re-serializa o corpo, o que pode alterar espaços em branco e quebrar a assinatura.Exemplo Node.js
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 o SDK
O SDK@authon/node fornece um auxiliar de verificação embutido que lida com a comparação de tempo constante para você:
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 Retry
Se seu endpoint retornar um código de status não 2xx ou não responder dentro de 10 segundos, o Authon tentará reenviar a entrega com backoff exponencial. Máximo de 3 tentativas no total.
| Tentativa | Atraso | Tempo Acumulado |
|---|---|---|
| Inicial | — | 0s |
| 1ª tentativa | 1 second | ~1s |
| 2ª tentativa | 2 seconds | ~3s |