Webhooks erklärt: Signierte Payloads und Retries

Backend2026-10-24TryQuickToolBox

Sie haben eine API entwickelt und müssen nun andere Dienste benachrichtigen, wenn Ereignisse eintreten. Sie richten einen Webhook-Endpunkt ein, stellen aber schnell fest, dass die zuverlässige Zustellung von HTTP-Anfragen schwieriger ist als es aussieht. Netzwerkfehler, böswillige Akteure und doppelte Ereignisse können Chaos verursachen. Dieser Leitfaden erklärt, wie Sie Webhooks mit signierten Payloads und Retries implementieren, um eine robuste Integration aufzubauen.

Was sind Webhooks?

Webhooks sind benutzerdefinierte HTTP-Callbacks. Wenn ein Ereignis in Ihrer Anwendung auftritt, senden Sie eine HTTP-POST-Anfrage an eine vom Abonnenten bereitgestellte URL. Dies ermöglicht Echtzeitkommunikation zwischen Diensten ohne Polling.

Beispielsweise könnte ein Zahlungsabwickler einen Webhook an Ihre App senden, wenn eine Abbuchung erfolgreich ist. Ihre App kann dann den Bestellstatus sofort aktualisieren.

Warum sollten Webhook-Payloads signiert werden?

Webhook-Endpunkte sind öffentlich zugänglich, sodass jeder gefälschte Anfragen senden kann. Ohne Verifizierung könnte Ihre App betrügerische Ereignisse verarbeiten. Das Signieren von Payloads stellt sicher, dass die Anfrage von Ihrem Dienst stammt und nicht manipuliert wurde.

Beim Signieren wird normalerweise ein Geheimnis verwendet, das zwischen Sender und Empfänger geteilt wird. Der Sender berechnet einen hashbasierten Nachrichtenauthentifizierungscode (HMAC) über den Payload und fügt ihn in einen Header ein. Der Empfänger berechnet den HMAC neu und vergleicht ihn.

So generieren und verifizieren Sie Signaturen

Die meisten Implementierungen verwenden HMAC-SHA256. Hier ist ein einfaches Beispiel in Python:

import hmac
import hashlib
import json

def generate_signature(payload, secret):
    body = json.dumps(payload, separators=(',', ':')).encode('utf-8')
    signature = hmac.new(secret.encode('utf-8'), body, hashlib.sha256).hexdigest()
    return signature

def verify_signature(payload, signature, secret):
    expected = generate_signature(payload, secret)
    return hmac.compare_digest(expected, signature)

Fügen Sie beim Senden des Webhooks die Signatur in einen Header wie X-Signature ein. Der Empfänger extrahiert den Rohbody, berechnet den HMAC neu und vergleicht. Verwenden Sie immer eine Vergleichsfunktion mit konstanter Zeit, um Timing-Angriffe zu verhindern.

Implementierung von Retries für zuverlässige Zustellung

Webhooks werden über das Internet gesendet, daher sind Fehler unvermeidlich. Ihr Server könnte ausgefallen sein, das Netzwerk langsam sein oder der Abonnent einen Fehler zurückgeben. Retries mit exponentiellem Backoff sind unerlässlich.

Retry-Strategie

Ein üblicher Ansatz ist, mit zunehmenden Verzögerungen erneut zu versuchen: 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden usw. Hören Sie nach einer maximalen Anzahl von Versuchen (z. B. 10) oder einem gesamten Zeitfenster (z. B. 24 Stunden) auf.

Wiederholen Sie nur bei bestimmten Bedingungen: Netzwerkfehler, 5xx-Antworten oder 429 (Too Many Requests). Wiederholen Sie nicht bei 4xx-Fehlern (außer 429), da diese auf einen Client-Fehler hinweisen, der durch Wiederholen nicht behoben wird.

Beispiel für Retry-Logik

Hier ist ein vereinfachter Retry-Mechanismus in Python unter Verwendung der requests-Bibliothek:

import requests
import time
from requests.exceptions import RequestException

def send_webhook(url, payload, secret, max_retries=5):
    headers = {'Content-Type': 'application/json'}
    signature = generate_signature(payload, secret)
    headers['X-Signature'] = signature
    
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=payload, headers=headers, timeout=10)
            if response.status_code < 500 and response.status_code != 429:
                return response.status_code
        except RequestException:
            pass
        
        # Exponentielles Backoff mit Jitter
        delay = (2 ** attempt) + (random.random() * 0.1)
        time.sleep(delay)
    
    return None  # Nach Wiederholungen fehlgeschlagen

In der Produktion würden Sie fehlgeschlagene Versuche in eine Warteschlange stellen und asynchron verarbeiten. Tools wie Celery oder Cloud-Warteschlangen (AWS SQS, Google Cloud Tasks) können helfen.

Best Practices für Webhook-Sicherheit

Umgang mit Duplikaten und Idempotenz

Retries können zu doppelten Zustellungen führen. Fügen Sie eine eindeutige Ereignis-ID in den Payload ein und lassen Sie den Empfänger verarbeitete IDs verfolgen. Wenn eine Ereignis-ID bereits gesehen wurde, ignorieren Sie sie.

Alternativ können Sie Ihre Ereignishandler idempotent gestalten. Beispielsweise sollte das Aktualisieren eines Datensatzes mit denselben Daten mehrmals denselben Effekt haben wie einmal.

Testen von Webhooks

Verwenden Sie Tools wie ngrok, um Ihren lokalen Server verfügbar zu machen und die Webhook-Zustellung zu testen. Simulieren Sie Fehler durch Rückgabe von Fehlercodes und überprüfen Sie, ob Retries wie erwartet erfolgen.

FAQ

Was ist ein signierter Webhook-Payload?

Ein signierter Payload enthält eine kryptografische Signatur (normalerweise HMAC), die es dem Empfänger ermöglicht zu überprüfen, ob die Anfrage von einer vertrauenswürdigen Quelle stammt und nicht verändert wurde.

Wie oft sollte ich einen fehlgeschlagenen Webhook wiederholen?

Das hängt von Ihren Zuverlässigkeitsanforderungen ab. Eine gängige Praxis sind 5-10 Wiederholungen mit exponentiellem Backoff über 24 Stunden. Ermöglichen Sie Abonnenten immer, eine Wiederholung manuell auszulösen.

Kann ich Webhooks ohne Signierung verwenden?

Ja, aber es ist riskant. Ohne Signierung kann jeder gefälschte Ereignisse senden. Signieren Sie Webhooks in der Produktion immer, um Betrug zu verhindern.

Bereit, Ihre Webhook-Payloads zu testen? Verwenden Sie unseren JSON Formatter, um JSON-Payloads vor dem Senden zu validieren und hübsch zu formatieren.