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-Z、a-z、0-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-Token | X-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 端點。
- 綁定來源與憑證。 在部署設定中明確指定每條路由的驗證契約。
- 先驗證再分發。 Telegram 檢查令牌標頭;已簽名的 UnifyPort 請求檢查原始內容 HMAC 與時間戳記新鮮度。
- 按正確結構驗證資料。 不要將 Telegram
Update傳入期待 UnifyPortmessage.received的處理器。 - 持久保存已接受的工作。 請求認證、冪等與業務授權應分開處理。
- 記錄失敗類型,不記錄密鑰。 排查時只需知道哪一項驗證失敗。
不要使用「任一標頭通過即可」的共用中介軟件。這會讓較弱或意外啟用的分支,成為另一條通過驗證的途徑。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。
令訊息接入變成一條穩定嘅產品管線。
先用統一嘅 API 跑通發送,再用標準事件將所有入站訊息接返去業務系統。