Webhooks erklärt: Signierte Payloads und Retries

Backend2026-10-17TryQuickToolBox

Sie haben gerade ein Zahlungsgateway integriert. Die Dokumentation sagt: „Wir senden einen Webhook an Ihren Endpunkt, wenn eine Zahlung erfolgreich ist.“ Sie richten eine einfache Route ein, testen sie lokal und deployen. Dann, in der Produktion, bemerken Sie doppelte Events, verpasste Benachrichtigungen und mysteriöse 500-Fehler. Webhooks scheinen einfach – bis sie es nicht mehr sind.

Dieser Leitfaden erklärt, wie Webhooks wirklich funktionieren, warum signierte Payloads wichtig sind und wie Sie eine Retry-Logik aufbauen, die Ihr System synchron hält, auch wenn etwas schiefgeht.

Was ist ein Webhook?

Ein Webhook ist ein HTTP-Callback: Ein System sendet eine HTTP-POST-Anfrage an eine von Ihnen bereitgestellte URL, wenn ein bestimmtes Ereignis eintritt. Im Gegensatz zum Polling, bei dem Sie wiederholt fragen „Ist etwas passiert?“, pushen Webhooks Ereignisse in nahezu Echtzeit zu Ihnen.

Häufige Anwendungsfälle sind:

Der Absender (z. B. Stripe, GitHub) ist der Webhook-Provider; Ihr Server ist der Webhook-Consumer.

Warum signierte Payloads unerlässlich sind

Ihr Webhook-Endpunkt ist öffentlich zugänglich. Jeder, der die URL kennt, kann gefälschte Events senden. Ohne Verifikation könnte ein Angreifer ein „Zahlung erfolgreich“-Event fälschen, und Sie könnten Waren kostenlos versenden.

Signierte Payloads lösen dies, indem sie eine kryptografische Signatur in den Request-Headern enthalten, die mit einem gemeinsamen Geheimnis generiert wird, das nur Ihnen und dem Provider bekannt ist. Wenn Sie einen Webhook empfangen, berechnen Sie die Signatur neu und vergleichen sie. Wenn sie übereinstimmen, ist die Payload authentisch.

Wie HMAC-Signaturen funktionieren

Die meisten Provider verwenden HMAC-SHA256. Der Provider berechnet:

signature = HMAC-SHA256(secret, payload)

und sendet sie in einem Header wie X-Signature. Ihr Server führt die gleiche Berechnung durch und prüft auf Gleichheit. Da das Geheimnis geheim ist, kann nur der Provider eine gültige Signatur erzeugen.

Signatur in der Praxis verifizieren

Hier ist ein minimales Node.js-Beispiel mit Express:

const crypto = require('crypto');
const express = require('express');
const app = express();

app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-signature'];
  const secret = process.env.WEBHOOK_SECRET;
  const payload = req.body; // raw Buffer

  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  if (signature !== expected) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event
  const event = JSON.parse(payload);
  console.log('Received event:', event.type);
  res.status(200).send('OK');
});

app.listen(3000);

Wichtig: Verwenden Sie für die Signaturverifikation immer den rohen Request-Body. Wenn Sie zuerst JSON parsen, kann die serialisierte Zeichenkette abweichen (Leerzeichen, Schlüsselreihenfolge) und die Signaturprüfung schlägt fehl.

Häufige Fallstricke

Retries: Fehler souverän behandeln

Netzwerke fallen aus, Server starten neu und Deployments finden statt. Webhook-Provider erwarten, dass Ihr Endpunkt vorübergehend nicht verfügbar sein könnte, also wiederholen sie fehlgeschlagene Zustellungen. Aber Retries bringen neue Herausforderungen mit sich: doppelte Events, ungeordnete Zustellung und Endlosschleifen, wenn Sie nicht aufpassen.

Wie Provider Retries durchführen

Die meisten Provider verwenden exponentielles Backoff: Sie warten nach dem ersten Fehler eine kurze Zeit, dann progressiv längere Intervalle. Zum Beispiel wiederholt Stripe bis zu 3 Tage mit zunehmenden Verzögerungen. GitHub wiederholt bis zu 8 Mal. Der genaue Zeitplan variiert, aber das Muster ist konsistent.

Ihr Endpunkt sollte schnell einen 2xx-Statuscode zurückgeben, um den Empfang zu bestätigen. Jeder andere Status (4xx, 5xx) signalisiert einen Fehler und löst einen Retry aus.

Idempotente Handler erstellen

Da Retries dasselbe Event mehrfach zustellen können, muss Ihr Handler idempotent sein: Die zweimalige Verarbeitung desselben Events sollte dieselbe Wirkung haben wie die einmalige Verarbeitung.

Häufige Strategien:

Beispiel mit einem einfachen In-Memory-Set (zur Veranschaulichung; verwenden Sie in der Produktion einen persistenten Speicher):

const processedEvents = new Set();

app.post('/webhook', (req, res) => {
  const event = req.body;
  if (processedEvents.has(event.id)) {
    return res.status(200).send('Already processed');
  }
  // Process event...
  processedEvents.add(event.id);
  res.status(200).send('OK');
});

Schnell antworten

Provider haben oft ein Timeout (z. B. 5 Sekunden). Wenn Ihr Handler schwere Verarbeitung durchführt, bestätigen Sie sofort und verarbeiten Sie asynchron. Beispielsweise können Sie das Event in eine Warteschlange legen und 200 zurückgeben.

Best Practices für zuverlässige Webhooks

  1. Verifizieren Sie immer Signaturen mit dem rohen Body und einem konstanten Vergleich.
  2. Verwenden Sie HTTPS für Ihren Endpunkt, um Abhören und Manipulation zu verhindern.
  3. Implementieren Sie Idempotenz, um doppelte Zustellungen zu handhaben.
  4. Loggen Sie alles – eingehende Payloads, Signaturen und Ihre Antworten – zum Debuggen.
  5. Überwachen Sie Fehler und richten Sie Alarme für wiederholte Fehler ein.
  6. Testen Sie mit echten Events über Provider-Dashboards oder CLI-Tools.
  7. Behandeln Sie ungeordnete Events, indem Sie Zeitstempel oder Sequenznummern in Ihre Logik einbeziehen.

Vergleich: Polling vs. Webhooks

AspektPollingWebhooks
LatenzAbhängig vom IntervallNahezu Echtzeit
ServerlastHoch (ständige Anfragen)Niedrig (nur bei Events)
KomplexitätEinfach zu implementierenErfordert Endpunkt, Sicherheit, Retries
ZuverlässigkeitSie kontrollieren RetriesProvider kontrolliert Retries

FAQ

Was ist eine Webhook-Signatur?

Eine Webhook-Signatur ist ein kryptografischer Hash (normalerweise HMAC-SHA256) der Payload, der mit einem gemeinsamen Geheimnis generiert wird. Sie ermöglicht dem Empfänger zu überprüfen, dass die Anfrage vom erwarteten Absender stammt und nicht manipuliert wurde.

Wie gehe ich mit doppelten Webhook-Events um?

Machen Sie Ihren Handler idempotent, indem Sie Event-IDs verfolgen oder Datenbankoperationen verwenden, die von Natur aus idempotent sind. Prüfen Sie, ob ein Event bereits verarbeitet wurde, bevor Sie Änderungen anwenden.

Was sollte mein Webhook-Endpunkt zurückgeben?

Geben Sie einen 2xx-Statuscode (z. B. 200 OK) zurück, sobald Sie das Event empfangen und validiert haben. Wenn Sie schwere Verarbeitung durchführen müssen, bestätigen Sie sofort und erledigen Sie die Arbeit asynchron.

Bereit, Ihre Webhook-Payloads zu testen? Verwenden Sie unseren JSON Formatter, um die JSON-Struktur eingehender Events zu inspizieren und zu validieren.