Webhook 詳解:簽章酬載與重試機制

Backend2026-10-07TryQuickToolBox

為什麼 Webhook 既強大又脆弱

Webhook 驅動了即時整合:付款通知、CI/CD 觸發、聊天訊息。但它們帶來兩大挑戰:安全性(如何確認請求來自預期的發送方?)以及可靠性(如果接收方離線怎麼辦?)。本文將說明如何透過簽章酬載與重試策略來解決這兩個問題。

什麼是 Webhook?

Webhook 是當事件發生時,由提供者發送給消費者的 HTTP POST 請求。與輪詢不同,Webhook 以近乎即時的方式推送資料,降低延遲與伺服器負載。提供者必須確保請求的真實性;消費者則必須可靠地處理它。

使用簽章酬載保護 Webhook

簽章酬載使用密鑰對請求主體建立密碼學簽章(通常為 HMAC-SHA256)。接收方重新計算簽章並與標頭中的簽章進行比對。若兩者相符,則酬載是真實且未被竄改的。

如何產生與驗證簽章

以下是典型的流程:

  1. 提供者與消費者共享一組密鑰(例如透過儀表板)。
  2. 提供者計算 HMAC-SHA256(secret, payload),並將其放入如 X-Signature 的標頭中發送。
  3. 消費者讀取原始主體,計算相同的 HMAC,並使用恆定時間函式進行比對。

Node.js 範例:

const crypto = require('crypto');

function verifySignature(secret, payload, signature) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload);
  const digest = hmac.digest('hex');
  return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
}

務必使用恆定時間比對以防止時序攻擊。切勿在驗證前解析主體——請使用原始主體中介軟體。

實作重試以確保可靠傳遞

即使有簽章,網路故障或暫時性中斷仍可能導致 Webhook 傳遞失敗。穩健的重試機制可確保最終送達。

重試策略

Python 重試邏輯範例:

import time
import requests

def send_webhook(url, payload, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=payload, timeout=5)
            if response.status_code == 200:
                return True
        except requests.RequestException:
            pass
        time.sleep(2 ** attempt)  # exponential backoff
    return False

Webhook 消費者的最佳實踐

比較:輪詢 vs Webhook

面向輪詢Webhook
延遲高(基於間隔)低(即時)
伺服器負載持續請求僅在事件發生時
複雜度簡單需要重試與安全性機制
使用情境小規模、不頻繁更新即時整合

常見問題

什麼是簽章 Webhook 酬載?

簽章酬載包含密碼學簽章(例如 HMAC),讓接收方能驗證請求來自可信任的來源,且未被竄改。

失敗的 Webhook 應該重試幾次?

沒有通用的次數,但通常以指數退避重試 3 至 5 次。之後,記錄事件以供人工審查。

我可以使用 JWT 取代 HMAC 來簽署 Webhook 嗎?

可以,有些提供者使用 JWT。原理相同:在信任酬載之前,先驗證權杖的簽章與聲明。

需要檢查 Webhook 酬載或日誌嗎?試試我們的 JSON Formatter,快速美化並驗證 JSON 酬載。