這篇將是 LINE Bot 教學系列的最後一篇,前面兩篇我們實作了 Heroku 和 GCP 兩種部署方式,最後將帶大家閱讀 LINE Bot SDK 中的 Authentication 驗證機制 (HMAC、Bearer Token),如何來確保訊息傳遞上的完整性 (integrity),以及是否有權限可以對 LINE Platform 發送請求。
關於 LINE Bot 教學系列的前面四篇文章可以參考:
- [Flask – LINE Bot 教學] 事前準備篇
- [Flask – LINE Bot 教學] Heroku 一鍵自動部署
- [Flask – LINE Bot 教學] GCP 部署 (Docker+Flask+Nginx)
- [Side Project] LINE Bot 自動化工具 (附 Github 程式碼)
Table
一. 簡單的 Flask + LINE Bot 範例
首先寫一個簡單的 Flask + LINE Bot 的 ehco 範例機器人,我們接下來會針對這份程式碼,來讀 LINE-Bot SDK 背後做了些什麼事
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import os from datetime import datetime # Flask from flask import Flask, abort, request # LINE Bot SDK from linebot import LineBotApi, WebhookHandler from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage app = Flask(__name__) line_bot_api = LineBotApi(os.environ.get("CHANNEL_ACCESS_TOKEN")) handler = WebhookHandler(os.environ.get("CHANNEL_SECRET")) # Signature Validation @app.route("/", methods=["POST"]) def callback(): if request.method == "POST": signature = request.headers["X-Line-Signature"] body = request.get_data(as_text=True) try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return "OK" # Message Response @handler.add(MessageEvent, message=TextMessage) def handle_message(event): get_message = event.message.text # Send To Line reply = TextSendMessage(text=f"{get_message}") line_bot_api.reply_message(event.reply_token, reply) |
二. 淺談 LINE-Bot 中的驗證機制
1. HMAC
▍什麼是 HMAC ?
Providing a way to check the integrity of information transmitted over or stored in an unreliable medium is a prime necessity in the world of open computing and communications.
RFC 2104
HMAC (Hash-based message authentication code) 是一種訊息驗證機制,可以確保傳遞訊息的完整性 (integrity) 和傳送人是否正確,HMAC 支援多種雜湊演算法 (MD5、SHA-256),並藉由 hash 要傳遞的 message 和 secret key 來產生 signature (如下圖左邊綠色區塊)。
當接收方接收到 傳送方 (例如:LINE platform) 傳送的 message 和 signature 後,會透過接收到的 message + 持有的 secret key 進行 hash 產生 signature (如下圖右邊灰色區塊)。
最後再將兩組 signature 進行比較,如果兩者不相同,代表傳遞的訊息有被竄改過。

▍LINE Bot SDK 如何使用 HMAC ?
當有人呼叫 Flask 的 API 時,首先從請求的 header 中拿到 X-Line-Signature
(如下範例 code 第四行)
1 2 3 4 5 |
@app.route("/", methods=["POST"]) def callback(): if request.method == "POST": signature = request.headers["X-Line-Signature"] body = request.get_data(as_text=True) |
接下來會放到 handler.handle
進行 Signature 的驗證,如果失敗則返回錯誤訊息:
1 2 3 4 5 6 |
try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return "OK" |
關於 handler.handle
可以從 LINE GitHub Python SDK 文件中 linebot > webhook.py > class SignatureValidator 第 85 行看到:

將請求中 body 的資料和我們持有的 Channel Secret 進行 hmac
後:
1 2 3 4 5 |
hmac.new( self.channel_secret, body.encode('utf-8'), hashlib.sha256 ).digest() |
與請求 header 中的 X-Line-Signature
比較,如果兩者不相符則則 raise signature_validator
的錯誤 (文件第 134行)。

▍小補充:關於 Custom Header
HTTP Header 使用 X- 前綴字來區隔 header 中的參數是標準參數或代表是 Custom 參數的參數,像這邊就是使用 X-Line-Signature
,但於 RFC 6648 中提到此方法已經不鼓勵 (discouraged) 使用 X-前綴字來命名。
2. Bearer Token
▍什麼是 Bearer Token ?
首先看看 RFC 6750 如何定義 Bearer Token:
Any party in possession of a bearer token (a “bearer”) can use it to get access to the associated resources (without demonstrating possession of a cryptographic key).
RFC 6750
Bearer Token 是由 Authorization Server 在 Resource Owner 的允許下核發給 Client ,Resource Server 只要認這個 Token 就可以認定 Client 已經經由 Resource Owner 的許可。
簡單來說 Bearer Token 就像是火車票,車票上會寫著搭乘的範圍 (例如台北到宜蘭)、有效的時間;而車長只認車票,只要持有的人都視為付過車票錢的人。
而為了防範 Token 在傳輸的過程外洩,須使用 SSL/TLS 來防護,也因此 LINE 的 Webhook URL 僅能填入 HTTPS URL

▍LINE Bot SDK 如何使用 Bearer Token ?
申請 LINE Developers 後,會拿到 Channel access token
和 Channel secret
,從剛剛 demo 的範例程式中,可以看到在一開始就會將這兩個參數傳給 LineBotApi 和 WebhookHandler 並實例化。
1 2 3 4 5 6 7 8 |
import os from flask import Flask, abort, request from linebot import LineBotApi, WebhookHandler app = Flask(__name__) line_bot_api = LineBotApi(os.environ.get("CHANNEL_ACCESS_TOKEN")) handler = WebhookHandler(os.environ.get("CHANNEL_SECRET")) |
可以從 LINE GitHub Python SDK 文件中 linebot>models>api.py 第61行 看到,LineBotApi 會將 channel_access_token
放到 'Authorization': 'Bearer ' + channel_access_token
中,未來當發送 request 請求給 LINE Platform 時,會驗證此 Token,來確認身份。

以上就是今天要介紹的 LINE-Bot 中使用到的驗證機制 HMAC 和 Bearer Token,那文章就到這邊告一個段落囉!有任何問題可以在以下留言~
關於 Flask 教學的延伸閱讀:
▍ Flask 教學系列目錄:
▍其他 Flask 相關教學: