webhooks
Requests signieren
Wie du deine Webhook-POSTs mit HMAC-SHA256 signierst, damit Spectra sie verifiziert.
Jeder POST auf einen Spectra-Webhook muss eine HMAC-SHA256-Signatur des Bodies tragen. Unsignierte oder mit ungültiger Signatur versehene Requests werden mit 401 Unauthorized abgelehnt.
Die Signatur
X-Spectra-Signature: sha256=<hex>
X-Spectra-Timestamp: <unix-ms>
Die Signatur wird über <timestamp>.<body> (Punkt-getrennt) berechnet:
import hmac, hashlib, time
secret = b"<deine secret bytes>"
ts = str(int(time.time() * 1000))
body = '{"action":"buy","symbol":"BTCUSDT","qty":1}'
mac = hmac.new(secret, f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
headers = {
"X-Spectra-Signature": f"sha256={mac}",
"X-Spectra-Timestamp": ts,
"Content-Type": "application/json",
}
Warum der Timestamp
Den Timestamp im signierten Payload zu binden, koppelt die Nachricht an einen Moment. Eine erfasste und nach dem 5-Minuten-Fenster wiederabgespielte Nachricht scheitert an der Verifikation — siehe Replay-Schutz.
Server-seitige Verifikation
Spectras Worker:
- Liest
X-Spectra-Timestamp. Lehnt ab, wenn fehlend oder älter als 5 Min. - Liest
X-Spectra-Signature. Lehnt ab, wenn fehlend oder verformt. - Berechnet HMAC über
<timestamp>.<body>mit dem Secret neu. - Vergleicht mit konstanter Zeit. Lehnt bei Mismatch ab.
- Validiert das Body-Schema (siehe Payload-Schema).
- Reicht zum Broker ein.
Häufige Fehler
- Body ohne Timestamp-Präfix signieren.
==statt konstanter Zeit-Vergleich auf deinem eigenen Server (Timing-Angriffsrisiko; nicht Spectras Problem, aber lohnt es, richtig zu machen, wenn du unseren Webhook proxierst).- JSON mit Whitespace-Unterschieden zur signierten Form senden — immer die exakten Bytes signieren, die du POSTest.