Ereignisbenennung
Ereignisse folgen dem Muster <object>.<action>. Jedes Ereignis trägt einen stabilen Typnamen, eine eindeutige svix-id und einen ISO 8601-Zeitstempel.
| Objekt | Aktionen |
|---|---|
user |
created, updated, deleted |
session |
created, ended, removed, revoked |
organization |
created, updated, deleted |
organizationMembership |
created, updated, deleted |
organizationInvitation |
created, accepted, revoked |
organizationDomain |
created, updated, deleted, verified, verification_failed |
authentication |
password_succeeded, password_failed, passkey_succeeded, passkey_failed, mfa_succeeded, mfa_failed, oauth_succeeded, oauth_failed, sso_succeeded, sso_failed, magic_auth_succeeded, magic_auth_failed, email_verification_succeeded, email_verification_failed, radar_risk_detected |
connection |
activated, deactivated, deleted, saml_certificate_renewed, renewal_required |
dsync |
activated, deleted, user.created, user.updated, user.deleted, group.created, group.updated, group.deleted, group.user_added, group.user_removed |
role |
created, updated, deleted |
permission |
created, updated, deleted |
email |
created (ausgelöst, wenn der Entwickler das Senden übernimmt) |
sms |
created (ausgelöst, wenn der Entwickler das Senden übernimmt) |
billing |
subscription.created, subscription.updated, paymentAttempt.succeeded, paymentAttempt.failed |
Payload-Struktur
Jede Webhook-Zustellung ist ein HTTP-POST mit Content-Type: application/json. Der Body enthält type, data und übergeordnete Metadaten-Header.
{
"type": "user.created",
"data": {
"id": "usr_01abc",
"email_addresses": [{ "email_address": "alice@example.com" }],
"created_at": 1700000000000
}
}Signaturprüfung
XID signiert jede Zustellung mit HMAC-SHA256. Prüfen Sie die Signatur, bevor Sie die Nutzlast verarbeiten. Lehnen Sie Zustellungen ab, die älter als 5 Minuten sind, um Replay-Angriffe zu verhindern.
| Kopfbereich | Beschreibung |
|---|---|
svix-id |
Eindeutige Nachrichten-ID. Verwenden Sie diese, um wiederholte Zustellungen zu deduplizieren. |
svix-timestamp |
Unix-Sekunden, als die Nachricht gesendet wurde. |
svix-signature |
Base64-kodiertes HMAC-SHA256 von ${svix-id}.${svix-timestamp}.${raw-body} mit dem Endpunkt-Signiergeheimnis. |
// Node.js / Cloudflare Workers example
async function verifyWebhook(request, secret) {
const svixId = request.headers.get('svix-id')
const svixTimestamp = request.headers.get('svix-timestamp')
const svixSignature = request.headers.get('svix-signature')
const body = await request.text()
// Reject messages older than 5 minutes
const ts = Number(svixTimestamp)
if (Math.abs(Date.now() / 1000 - ts) > 300) {
throw new Error('webhook timestamp out of tolerance')
}
const signedContent = `${svixId}.${svixTimestamp}.${body}`
const keyData = Uint8Array.from(atob(secret), c => c.charCodeAt(0))
const key = await crypto.subtle.importKey(
'raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']
)
const msgData = new TextEncoder().encode(signedContent)
// svix-signature may contain multiple comma-separated values
for (const sig of svixSignature.split(' ')) {
const prefix = 'v1,'
if (!sig.startsWith(prefix)) continue
const sigBytes = Uint8Array.from(atob(sig.slice(prefix.length)), c => c.charCodeAt(0))
const valid = await crypto.subtle.verify('HMAC', key, sigBytes, msgData)
if (valid) return JSON.parse(body)
}
throw new Error('invalid webhook signature')
}Wiederholungen und unzustellbare Nachrichten
- Fehlgeschlagene Zustellungen werden mit exponentiellem Backoff wiederholt. Nach der maximalen Anzahl von Wiederholungen wird die Nachricht zur manuellen Prüfung in den Dead-Letter-Speicher in D1 geschrieben.
- Die Zustellung ist über Cloudflare Queues vom Authentifizierungspfad entkoppelt. Ein langsamer oder nicht verfügbarer Endpunkt beeinträchtigt die Anmelde-Latenz nicht.
- Verwenden Sie den
svix-id-Header, um Zustellungen auf Ihrer Seite zu deduplizieren. Wiederholungen tragen dieselbesvix-idwie der ursprüngliche Versuch.
flowchart LR XID --> Queue Queue -->|HTTPS| Endpoint Endpoint -->|2xx| ACK Endpoint -->|non-2xx| Retry Retry --> Queue Retry -->|max_retries| dlq["D1 DLQ"]
Manuelles Wiederholen
Verwenden Sie POST /v1/webhooks/:endpointId/replay, um Ereignisse nach Nachrichten-ID oder Zeitbereich zu wiederholen. Wiederholte Ereignisse tragen neue svix-id-Werte, behalten aber den ursprünglichen type und data.
# Replay events from the last hour
curl -X POST https://xid.dev/v1/webhooks/whe_xxx/replay \
-H 'Authorization: Bearer sk_live_xxx' \
-H 'Content-Type: application/json' \
-d '{ "since": "2024-01-01T00:00:00Z", "until": "2024-01-01T01:00:00Z" }'Ereignis-API
Zusätzlich zu Push-Webhooks stellt XID unter GET /v1/events einen geordneten, unveränderlichen Ereignisstrom mit Cursor-Paginierung bereit. Rufen Sie den Stream ab, um zuverlässige Synchronisierung ohne fehlende Ereignisse zwischen Webhook-Wiederholungen aufzubauen.
curl 'https://xid.dev/v1/events?limit=100&after=evt_xxx' \
-H 'Authorization: Bearer sk_live_xxx'