Inbound Webhook 簽章
每次 inbound POST 都必須帶 X-Timestamp、X-Nonce、X-Signature。timestamp 使用 Unix seconds,與伺服器時間的差距不可超過正負 300 秒。nonce 必須是 1 到 128 個可見、無空白的 ASCII 字元,建議使用 UUID;同一 webhook 的 nonce 會保留 600 秒,重複使用會被拒絕。
使用只顯示一次的 signing secret,針對下列「完全相同的原始 bytes」計算小寫十六進位 HMAC-SHA256:
timestamp + ":" + nonce + ":" + raw_request_body
簽完後不可再 parse 並重新序列化 JSON;空白或 key 順序改變都會讓簽章失效。
Curl:
TS=$(date +%s); NONCE=$(uuidgen); BODY='{"event":"example"}'SIG=$(printf '%s:%s:%s' "$TS" "$NONCE" "$BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" -hex | awk '{print $2}')curl -X POST "$WEBHOOK_URL" -H "Content-Type: application/json" -H "X-Timestamp: $TS" -H "X-Nonce: $NONCE" -H "X-Signature: $SIG" -d "$BODY"Node:
const body = JSON.stringify({ event: "example" });const ts = Math.floor(Date.now() / 1000).toString();const nonce = crypto.randomUUID();const signature = crypto.createHmac("sha256", secret).update(`${ts}:${nonce}:${body}`).digest("hex");Python:
body = b'{"event":"example"}'signed = timestamp.encode() + b":" + nonce.encode() + b":" + bodysignature = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()Related actions
Section titled “Related actions”arinova.webhook.create_webhook, arinova.webhook.get_webhook
Also known as
webhook 簽章, HMAC, X-Signature, X-Timestamp, X-Nonce, 發送端整合
Build a7f47a5ca54ddcf7806cd48b81ce1b9827042766