← 所有文章
對比選型

Telegram Webhook secret_token 與 HMAC:接收端應驗證甚麼

Telegram Bot API 的 secret_token 並非 HMAC 簽名。透過 setWebhook 設定後,Telegram 會將相同的值放入 X-Telegram-Bot-Api-Secret-Token 標頭,接收端再與本地設定的令牌比較。UnifyPort 採用另一套契約:啟用簽名後,要以時間戳記及原始請求內容計算 HMAC-SHA256,再驗證 X-Device-Signature。兩種檢查不能互換。

先分清驗證對象

  • Telegram 標頭直接傳送共用憑證,不是根據 JSON 內容計算的摘要。
  • UnifyPort 透過端點的 signing_secret,將原始內容及 X-Device-Timestamp 綁定到簽名。
  • 兩種接收端都需要 HTTPS、密鑰保護及冪等處理。
  • 驗證方式應由可信的路由設定決定,不能依賴未驗證的 JSON provider 欄位,或看哪個標頭存在就接受哪種方式。

本文處理請求驗證,而非選擇通訊身分。如果還未決定用機械人還是現有通訊帳戶,可先閱讀 Telegram Bot API webhook 與統一入站 webhook 比較

Telegram secret_token 實際證明甚麼

Telegram 官方 Bot API 文件secret_token 列為 setWebhook 的可選參數:長度為 1–256 個字元,只允許 A-Za-z0-9_-。設定後,每次 webhook 請求都會透過 X-Telegram-Bot-Api-Secret-Token 傳送該值。

若接收端要求這項保護,缺少或不相符的標頭就不應進入可信處理佇列。完全相符代表請求方持有設定的值,但不會建立該值與請求內容之間的獨立密碼學關聯。

這個分別在代理或轉發服務尤其重要:可以讀取令牌的組件,也可以用同一令牌提交另一段內容。HTTPS 保護傳輸連線;靜態標頭本身不會偵測 TLS 終止後發生的內容變更。這是信任邊界的分別,並非否定官方 Bot API。

建議使用專屬 webhook 憑證,不要重用 bot token,也不要將密鑰貼到公開的請求擷取服務。存取紀錄、追蹤資料匯出及支援截圖都應隱藏敏感值。

靜態令牌與內容簽名比較

HMAC 是使用共用密鑰的訊息認證機制。UnifyPort 文件要求重新計算指定輸入的摘要,不是直接將簽名標頭與密鑰比較。

問題Telegram Bot API webhook已簽名的 UnifyPort webhook
設定項目setWebhook.secret_token端點的 signing_secret
驗證標頭X-Telegram-Bot-Api-Secret-TokenX-Device-Signature
收到的值設定的令牌本身十六進制 HMAC-SHA256 摘要
是否涵蓋內容是,原始位元組
是否涵蓋時間戳記是,X-Device-Timestamp
接收端操作比較標頭與令牌重新計算及比較摘要
是否保證只處理一次

UnifyPort 的簽名輸入必須是:

<X-Device-Timestamp>.<raw request body>

時間戳記使用 RFC 3339 UTC 格式,中間是一個字面上的點號。重新格式化 JSON、改動空白,或先解析再序列化,都可能改變簽名所涵蓋的位元組。signing_secret 是 HMAC 密鑰,不是標頭應直接等於的值。

signing_secret 為空,UnifyPort 會停用簽名,不傳送 X-Device-Signature。要求簽名的接收端應拒絕這類請求,而不是靜默切換至其他驗證模式。

為兩種請求保留獨立入口

建議為原生 Telegram 更新與 UnifyPort 事件設定不同的應用程式路由。這是應用設計建議,不是新增的平台 API 端點。

  1. 綁定來源與憑證。 在部署設定中明確指定每條路由的驗證契約。
  2. 先驗證再分發。 Telegram 檢查令牌標頭;已簽名的 UnifyPort 請求檢查原始內容 HMAC 與時間戳記新鮮度。
  3. 按正確結構驗證資料。 不要將 Telegram Update 傳入期待 UnifyPort message.received 的處理器。
  4. 持久保存已接受的工作。 請求認證、冪等與業務授權應分開處理。
  5. 記錄失敗類型,不記錄密鑰。 排查時只需知道哪一項驗證失敗。

不要使用「任一標頭通過即可」的共用中介軟件。這會讓較弱或意外啟用的分支,成為另一條通過驗證的途徑。Telegram 令牌尤其不能取代 UnifyPort 路由所要求的 HMAC。

第二套契約的實作細節可參考 HMAC 重播防護與重試處理。訊息 JSON 中的時間欄位,不能取代受投遞簽名保護的時間戳記。

上線前的驗收測試

以下是建議測試,並非已執行的測試結果。請在隔離環境使用自己控制的憑證。

測試接收端預期行為
Telegram 標頭缺少或不正確在可信處理前拒絕
Telegram 令牌正確,但內容被更改單靠令牌無法發現;仍需資料驗證及可信的傳輸邊界
UnifyPort 內容在簽名後被更改摘要不符,拒絕
UnifyPort 簽名有效,但時間超出設定窗口按新鮮度政策拒絕
向 UnifyPort 路由提交 Telegram 令牌拒絕,不改變驗證模式
相同的真實一般事件再次投遞冪等接受,不重複執行業務動作

新鮮度窗口應配合時鐘準確度及投遞條件,不要照搬另一平台的數值。驗證成功亦不代表訊息中的所有指令都有權執行。

UnifyPort 的適用範圍及限制

UnifyPort 非官方接口提供已連接通訊帳戶的標準化事件。HMAC 保護的是 UnifyPort 至你的接收端這段交接,不是 Telegram 原生簽名,也不是 Telegram 用戶端到端作者身分的證明。

如果產品本身就是 Telegram 機械人,在該入口按 Telegram 文件實作保護即可,毋須只為改變驗證方式而遷移平台。若透過 UnifyPort 建立帳戶級或跨渠道佇列,便應遵循它的獨立契約,並在建立 webhook 端點時啟用簽名。

常見問題

應該用 Telegram secret_token 計算 HMAC 嗎?

驗證官方 Bot API 的密鑰標頭時不需要。應比較標頭與設定的令牌,不要自行為直接傳送令牌的標頭設計內容簽名算法。

可以直接比較 X-Device-Signature 與 signing_secret 嗎?

不可以。先對文件指定的「時間戳記加原始請求內容」計算 HMAC-SHA256,再比較收到的十六進制簽名。

兩種機制能防止重複處理嗎?

不能。認證與去重是不同工作。應持久保存已接受的任務,並讓下游操作保持冪等;HMAC 本身不保證只處理一次。

下一步及來源

開發 UnifyPort 接收端時,以 webhook 投遞與簽名驗證文件作為實作契約。

來源核對日期:2026-09-17。

UnifyPort API

令訊息接入變成一條穩定嘅產品管線。

先用統一嘅 API 跑通發送,再用標準事件將所有入站訊息接返去業務系統。