Callbacks
Task-Callback-Lieferungen sicher empfangen und verifizieren.
Verwende Callbacks, um Task-Lifecycle-Ereignisse an einem öffentlichen HTTPS- Endpunkt zu empfangen. Überprüfe jeden Callback, bevor du seinen JSON-Body verarbeitest, damit nur für dein Konto signierte Zustellungen den Anwendungszustand ändern können.
Eine Callback-URL konfigurieren
Fügen Sie beim Erstellen einer Task eine öffentliche HTTPS-callback_url hinzu. Der Ereignisinhalt und die Lebenszyklusstatus hängen vom Endpunkt ab; entnehmen Sie die Callback-Nutzlasten der API-Referenz des jeweiligen Endpunkts.
{
"model": "flux-2-pro-text-to-image",
"prompt": "A product photograph on a clean studio background",
"callback_url": "https://your-domain.com/webhooks/runapi"
}
Ein Callback-Secret erstellen
Folgen Sie dem Authentifizierungsleitfaden, um sich anzumelden, öffnen Sie dann API-Schlüssel und erstellen Sie einen Callback-Secret für das Konto, das den Task erstellt. Speichern Sie den Wert in einem Secret-Manager und stellen Sie ihn nur Ihrem Callback-Empfänger zur Verfügung. Es handelt sich nicht um einen API-Schlüssel und darf niemals in einer Task-Anfrage gesendet werden.
Das Secret signiert Callbacks für dieses Konto. Durch Rotieren ändert sich die Signatur für spätere Lieferungen. Aktualisieren Sie daher sofort alle Callback-Empfänger und halten Sie beide Werte nur so lange verfügbar, wie es zur Verarbeitung laufender Lieferungen nötig ist.
Eine Callback-Signatur überprüfen
Jeder Callback ist ein HTTP-POST mit Content-Type: application/json. RunAPI fügt dieser Anfrage keinen Authorization-Header hinzu. Überprüfen Sie diese Header vor der Deserialisierung des Bodys:
X-Callback-Id
Eindeutiger Bezeichner für diesen Zustellversuch.
X-Callback-Timestamp
Unix-Zeitstempel in Sekunden zum Zeitpunkt der Signierung der Zustellung.
X-Callback-Signature
Base64-kodierte HMAC-SHA-256-Signatur.
Erstellen Sie den signierten Wert genau wie folgt, indem Sie die unveränderten Anfrage-Body-Bytes verwenden:
X-Callback-Id + "." + X-Callback-Timestamp + "." + raw request body
Decodieren Sie das Callback-Secret mit Base64, berechnen Sie HMAC-SHA-256 über diesen Wert, codieren Sie das Ergebnis mit Base64 und vergleichen Sie es mit
X-Callback-Signature mittels eines zeitkonstanten Vergleichs. Parsen und re-serialisieren Sie das JSON nicht, bevor Sie es verifizieren.
JavaScript
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyCallback({headers, rawBody, callbackSecret}) {
const callbackId = headers["x-callback-id"];
const timestamp = Number(headers["x-callback-timestamp"]);
const signature = headers["x-callback-signature"];
if (!callbackId || !signature || !Number.isSafeInteger(timestamp)) return false;
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const signedContent = `${callbackId}.${timestamp}.${rawBody}`;
const expected = createHmac("sha256", Buffer.from(callbackSecret, "base64"))
.update(signedContent, "utf8")
.digest();
const received = Buffer.from(signature, "base64");
return expected.length === received.length && timingSafeEqual(expected, received);
}
Übergeben Sie den rohen Request-Body-String des Frameworks an rawBody; rufen Sie
JSON.stringify nicht auf geparsten Daten auf.
Python
import base64
import hashlib
import hmac
import time
def verify_callback(headers, raw_body, callback_secret):
callback_id = headers.get("X-Callback-Id")
timestamp = headers.get("X-Callback-Timestamp")
signature = headers.get("X-Callback-Signature")
if not callback_id or not timestamp or not signature:
return False
try:
timestamp = int(timestamp)
secret = base64.b64decode(callback_secret, validate=True)
received = base64.b64decode(signature, validate=True)
except (ValueError, TypeError):
return False
if abs(time.time() - timestamp) > 300:
return False
signed_content = f"{callback_id}.{timestamp}.{raw_body}".encode("utf-8")
expected = hmac.new(secret, signed_content, hashlib.sha256).digest()
return hmac.compare_digest(expected, received)
Übergeben Sie den exakten rohen Request-Body-String, den Ihr HTTP-Framework
empfangen hat, als raw_body.
Lieferungen sicher verarbeiten
- Senden Sie eine
2xx-Antwort nur dann, wenn der Callback zur Verarbeitung akzeptiert wurde. Nach einer Nicht-2xx-Antwort oder einem Transportfehler wird die Zustellung bis zu 10-mal erneut versucht. - Antworten Sie innerhalb von 15 Sekunden. Stellen Sie langsamere Aufgaben nach der Überprüfung in eine Warteschlange, anstatt die HTTP-Antwort zu blockieren.
- Weisen Sie Callbacks mit fehlenden Signatur-Headern, einer ungültigen Signatur oder einem Zeitstempel außerhalb des von Ihrem Empfänger definierten Toleranzfensters ab.
Überprüfung debuggen
- Signaturkonflikt: Vergewissern Sie sich, dass das Callback-Secret zum selben Konto wie die Aufgabe gehört, dekodieren Sie es mit Base64 und signieren Sie den ursprünglichen Body anstelle von geparsetem JSON.
- Fehlende Signatur-Header: Erstellen Sie ein Callback-Secret, bevor Sie Callbacks für Statusänderungen verwenden.
- Zeitstempel abgelehnt: Synchronisieren Sie die Uhr des Empfängers und verwenden Sie eine für Ihre Bereitstellung geeignete Toleranz.
Für Einrichtungs- und Lebenszyklushinweise kehren Sie zum Task API Quickstart zurück.