Webhooks erklärt: Signierte Payloads und Retries

Backend2026-11-08TryQuickToolBox

Sie haben gerade den Webhook eines Zahlungsanbieters integriert. Die Dokumentation besagt: „Wir senden eine POST-Anfrage an Ihren Endpunkt, wenn eine Zahlung erfolgreich ist.“ Einfach, oder? Dann bemerken Sie doppelte Ereignisse, verpasste Benachrichtigungen und eine Sicherheitswarnung über gefälschte Anfragen. Webhooks sind im Konzept einfach, aber in der Produktion knifflig. Dieser Artikel erklärt, wie Sie Webhooks korrekt implementieren, indem Sie signierte Payloads und Retries verwenden, damit Sie zuverlässige und sichere Integrationen erstellen können.

Was sind Webhooks?

Ein Webhook ist eine umgekehrte API: Statt dass Ihre Anwendung einen Dienst nach Updates abfragt, sendet der Dienst Ereignisse per HTTP POST an Ihren Endpunkt. Das ist effizient und nahezu in Echtzeit. Häufige Anwendungsfälle sind Zahlungsbenachrichtigungen, CI/CD-Trigger und Chat-Integrationen.

Aber Webhooks bringen Herausforderungen mit sich: Woher wissen Sie, dass die Anfrage wirklich vom Anbieter stammt? Was, wenn Ihr Server ausgefallen ist? Was, wenn dasselbe Ereignis zweimal ankommt? Lassen Sie uns diese nacheinander angehen.

Webhooks mit signierten Payloads absichern

Jeder kann eine HTTP-Anfrage an Ihren Endpunkt senden. Ohne Verifikation könnten Angreifer Ereignisse fälschen, was zu Betrug oder Datenverfälschung führen kann. Die Standardlösung besteht darin, den Payload mit einem gemeinsamen Geheimnis zu signieren.

Wie HMAC-Signaturen funktionieren

Der Anbieter und Sie teilen einen geheimen Schlüssel. Für jedes Ereignis berechnet der Anbieter einen HMAC (Hash-based Message Authentication Code) des Request-Bodys mit diesem Geheimnis und sendet die Signatur in einem Header (z. B. X-Signature). Sie berechnen den HMAC auf Ihrer Seite neu und vergleichen. Wenn sie übereinstimmen, ist die Anfrage authentisch und unverändert.

Hier ist ein minimales Beispiel in Python mit Flask:

import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = b'your_shared_secret'

@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Signature')
    if not signature:
        abort(400, 'Missing signature')
    body = request.get_data()
    expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, signature):
        abort(401, 'Invalid signature')
    # Process the event
    return '', 200

Verwenden Sie immer hmac.compare_digest für einen Vergleich mit konstanter Zeit, um Timing-Angriffe zu verhindern. Verifizieren Sie außerdem die Signatur, bevor Sie den JSON-Body parsen, um unnötige Verarbeitung zu vermeiden.

Best Practices für Signaturen

Fehler mit Retries behandeln

Webhooks sind aus Sicht des Anbieters Fire-and-Forget, aber Ihr Endpunkt könnte vorübergehend nicht verfügbar sein. Um die Zustellung sicherzustellen, implementieren Anbieter Retry-Richtlinien. Als Empfänger müssen Sie auf Retries und Duplikate vorbereitet sein.

Von Anbietern verwendete Retry-Strategien

Die meisten Anbieter wiederholen mit exponentiellem Backoff: z. B. sofort, dann nach 1 Minute, 5 Minuten, 30 Minuten usw., bis zu einer maximalen Anzahl von Versuchen (oft 5–10). Einige ermöglichen es Ihnen auch, einen Retry-Zeitplan zu konfigurieren. Das genaue Verhalten variiert, lesen Sie daher die Dokumentation des Anbieters.

Ihren Endpunkt für Retries entwerfen

Ihr Endpunkt sollte:

Beispiel für eine Idempotenzprüfung in Python:

processed_events = set()  # In production, use a database or cache

@app.route('/webhook', methods=['POST'])
def webhook():
    # ... signature verification ...
    event = request.json
    event_id = event['id']
    if event_id in processed_events:
        return '', 200  # Already processed
    # Process event
    processed_events.add(event_id)
    return '', 200

Testen Ihrer Webhook-Implementierung

Bevor Sie live gehen, testen Sie Ihren Endpunkt gründlich:

  1. Simulieren Sie signierte Anfragen: Schreiben Sie Unit-Tests, die gültige und ungültige Signaturen generieren.
  2. Testen Sie Retry-Szenarien: Simulieren Sie Fehler und stellen Sie sicher, dass Ihr Endpunkt Duplikate behandelt.
  3. Verwenden Sie Anbieter-Tools: Viele Anbieter bieten eine CLI oder ein Dashboard zum Senden von Testereignissen.
  4. Überwachen und protokollieren Sie: Protokollieren Sie eingehende Ereignisse (ohne sensible Daten) und richten Sie Warnungen für Signaturfehler oder hohe Fehlerraten ein.

Vergleich: Polling vs. Webhooks

AspektPollingWebhooks
LatenzAbhängig vom Intervall (z. B. Minuten)Nahezu Echtzeit
ServerlastHoch (häufige Anfragen)Niedrig (nur bei Ereignissen)
KomplexitätEinfach zu implementierenErfordert Signaturverifikation und Retry-Behandlung
ZuverlässigkeitSie kontrollieren RetriesAnbieter kontrolliert Retries; Sie müssen Duplikate behandeln

FAQ

Wie verifiziere ich eine Webhook-Signatur?

Berechnen Sie den HMAC des rohen Request-Bodys mit dem gemeinsamen Geheimnis und vergleichen Sie ihn mit dem Signatur-Header unter Verwendung einer Vergleichsfunktion mit konstanter Zeit. Verifizieren Sie immer, bevor Sie den Payload verarbeiten.

Was sollte mein Endpunkt zurückgeben, um einen Webhook zu bestätigen?

Geben Sie einen 2xx-Statuscode (z. B. 200 OK) zurück, sobald Sie das Ereignis empfangen und zur Verarbeitung in die Warteschlange gestellt haben. Vermeiden Sie lange Verarbeitung im Request-Handler, um Timeouts zu verhindern.

Wie kann ich doppelte Webhook-Zustellungen behandeln?

Verwenden Sie einen Idempotenzschlüssel aus dem Ereignis-Payload (oder eine eindeutige Ereignis-ID), um verarbeitete Ereignisse zu verfolgen. Speichern Sie diese IDs in einer Datenbank oder einem Cache und überspringen Sie die Verarbeitung, wenn die ID zuvor gesehen wurde.

Bereit, Ihre Webhook-Payloads zu testen? Verwenden Sie unseren JSON Formatter, um den JSON-Body eingehender Webhooks übersichtlich zu formatieren und zu validieren, was das Debuggen erleichtert.