Webhooks erklärt: Signierte Payloads und Retries
Sie haben gerade den Webhook eines Zahlungsanbieters integriert, um Transaktionsaktualisierungen zu erhalten. In Tests funktioniert alles, aber in der Produktion bemerken Sie fehlende Ereignisse während Traffic-Spitzen oder doppelte Abbuchungen, wenn der Anbieter Retries durchführt. Webhooks sind im Konzept einfach, aber in der Praxis knifflig: Sie überqueren Netzwerkgrenzen, können verzögert, dupliziert oder gefälscht werden. Dieser Artikel erklärt, wie Sie robuste Webhook-Consumer und -Producer mit signierten Payloads und intelligenten Retry-Strategien erstellen.
Was sind Webhooks?
Webhooks sind benutzerdefinierte HTTP-Callbacks, die durch Ereignisse ausgelöst werden. Wenn etwas in einem Quellsystem passiert (z. B. eine neue Bestellung), sendet es eine HTTP-POST-Anfrage an eine von Ihnen bereitgestellte URL. Im Gegensatz zum Polling übertragen Webhooks Daten nahezu in Echtzeit, was Latenz und Serverlast reduziert.
Webhooks bringen jedoch Herausforderungen mit sich: sicherzustellen, dass die Anfrage tatsächlich vom erwarteten Absender stammt, Fehler ordnungsgemäß zu behandeln und doppelte Verarbeitung zu vermeiden.
Webhooks mit signierten Payloads absichern
Ohne Verifizierung kann jeder gefälschte Anfragen an Ihren Webhook-Endpunkt senden. Signierte Payloads lösen dieses Problem, indem sie eine kryptografische Signatur enthalten, die Sie validieren können.
Wie HMAC-Signaturen funktionieren
Der Absender berechnet einen hashbasierten Message Authentication Code (HMAC) unter Verwendung eines gemeinsamen Geheimnisses und des Request-Bodys. Die Signatur wird in einem Header gesendet (z. B. X-Signature). Sie berechnen den HMAC auf Ihrer Seite neu und vergleichen ihn.
// Node.js example: verifying a webhook signature
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Verwenden Sie immer eine Vergleichsfunktion mit konstanter Zeit wie timingSafeEqual, um Timing-Angriffe zu verhindern.
Fügen Sie einen Zeitstempel hinzu
Um Replay-Angriffe zu verhindern, fügen Sie einen Zeitstempel in den signierten Payload ein und lehnen Sie Anfragen ab, die älter als einige Minuten sind (z. B. 5 Minuten). Der Zeitstempel sollte Teil der signierten Daten sein.
Zuverlässige Retries implementieren
Netzwerkprobleme oder vorübergehende Serverfehler können dazu führen, dass die Webhook-Zustellung fehlschlägt. Ein robuster Absender wiederholt fehlgeschlagene Zustellungen mit exponentiellem Backoff.
Retry-Strategie
- Exponentielles Backoff: Warten Sie zwischen jedem Retry länger (z. B. 1s, 2s, 4s, 8s...).
- Maximale Retries: Legen Sie ein Limit fest (z. B. 5 Versuche), um Endlosschleifen zu vermeiden.
- Dead-Letter-Queue: Speichern Sie das Ereignis nach maximalen Retries zur manuellen Überprüfung.
- Idempotenz: Fügen Sie eine eindeutige Ereignis-ID hinzu, damit der Empfänger Duplikate entfernen kann.
Beispiel: Retry mit Backoff in Python
import time
import requests
from requests.exceptions import RequestException
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 < 500:
return True # success or client error (no retry)
except RequestException:
pass
time.sleep(2 ** attempt) # exponential backoff
return False
Best Practices für Webhook-Consumer
- Schnell antworten: Bestätigen Sie den Empfang mit einem 2xx-Status, bevor Sie mit der Verarbeitung beginnen. Stellen Sie die Arbeit asynchron in eine Warteschlange.
- Signaturen validieren: Überprüfen Sie immer die Signatur, bevor Sie dem Payload vertrauen.
- Duplikate behandeln: Verwenden Sie die Ereignis-ID, um eine idempotente Verarbeitung sicherzustellen.
- Alles protokollieren: Führen Sie Protokolle über empfangene Webhooks zur Fehlerbehebung.
Vergleich: Webhooks vs. Polling
| Aspekt | Webhooks | Polling |
|---|---|---|
| Latenz | Nahezu Echtzeit | Abhängig vom Intervall |
| Serverlast | Gering (nur Push) | Hoch (häufige Anfragen) |
| Komplexität | Höher (Endpunkt, Sicherheit erforderlich) | Geringer |
| Zuverlässigkeit | Erfordert Retries | Inhärent wiederholt |
FAQ
Was ist ein signierter Webhook-Payload?
Ein signierter Payload enthält eine kryptografische Signatur (normalerweise HMAC), die es dem Empfänger ermöglicht, die Authentizität und Integrität der Anfrage zu überprüfen.
Wie oft sollte ich einen fehlgeschlagenen Webhook wiederholen?
Eine gängige Praxis sind 3–5 Retries mit exponentiellem Backoff, aber es hängt von Ihrem SLA und der Kritikalität des Ereignisses ab.
Kann ich Webhooks ohne HTTPS verwenden?
Nein, verwenden Sie immer HTTPS, um den Payload und die Signatur vor Abfangen zu schützen. Reines HTTP legt sensible Daten offen.
Beim Debuggen von Webhook-Payloads müssen Sie möglicherweise JSON schnell formatieren. Probieren Sie unseren JSON Formatter, um JSON-Antworten hübsch zu formatieren und zu validieren.