Hat ein Webhook ein Secret, wird jede Anfrage mit HMAC-SHA256 über den Timestamp-Header und den rohen Body signiert.
X-Mateflow-Signature = "sha256=" + hex(
HMAC-SHA256(secret, X-Mateflow-Timestamp + "." + raw_request_body)
)
- Verwenden Sie die rohen Bytes. Im HTML-Kontext besondere Zeichen können im Body maskiert sein. Wenn Sie das JSON parsen und erneut serialisieren, entstehen daher andere Bytes, und die Signatur stimmt nicht überein.
- Nehmen Sie den Timestamp aus dem Header, nicht aus dem Body. Beim manuellen erneuten Senden werden nur der Timestamp im Header und die Signatur aktualisiert.
- Eine Timestamp-Prüfung stört die Wiederholungen nicht. Jede automatische Wiederholung und jedes manuelle erneute Senden wird neu signiert, ein Fenster von 5 Minuten genügt also.
const crypto = require('crypto');
// rawBody must be the untouched bytes, e.g. from express.raw({ type: 'application/json' }).
function verifyMateflowSignature(rawBody, headers, secret, toleranceSeconds = 300) {
const timestamp = headers['x-mateflow-timestamp'];
const received = headers['x-mateflow-signature'] || '';
if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) {
return false;
}
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(`${timestamp}.`)
.update(rawBody)
.digest('hex');
const a = Buffer.from(received);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}import hashlib
import hmac
import time
def verify_mateflow_signature(raw_body: bytes, headers, secret: str, tolerance_seconds: int = 300) -> bool:
timestamp = headers.get("X-Mateflow-Timestamp", "")
received = headers.get("X-Mateflow-Signature", "")
if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > tolerance_seconds:
return False
signed = timestamp.encode() + b"." + raw_body
expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(received.encode(), expected.encode())Testvektor
Prüfen Sie mit diesen Werten Ihre Signaturberechnung. Der Timestamp ist abgelaufen; lockern Sie beim Testen daher Ihr Zeitfenster.
secret my_signing_secret
X-Mateflow-Timestamp 1793664000
raw body (UTF-8) {"event":"member.joined","data":{"username":"张三"}}
X-Mateflow-Signature sha256=3f4c83828ce0086150c9bd48c1654899357b7c05265c1d1b6c172225ee04b4b4Secret wechseln
Ein neues Secret gilt, sobald es gespeichert ist, und auch Wiederholungen in der Warteschlange werden damit signiert. Es gibt keine Phase, in der Mateflow mit beiden signiert; lassen Sie Ihren Empfänger daher während des Wechsels sowohl das alte als auch das neue Secret akzeptieren.