🔒 為什麼我們需要「帶參數」的驗證連結?
打造一個既方便又具備初步安全性的下載流程
在設計「自動化考題下載」或「資料索取」系統時,我們常遇到一個難題:如何確認點擊連結的人真的是本人?
如果直接把下載網址寄給使用者,連結可能會被隨意轉傳。透過在 Email 連結中加入一個「加密過的 ID 或電話」,當使用者點擊後,我們可以先引導他到一個驗證頁面(例如輸入電話比對)。這不僅提升了專業感,也能有效保護你的數位資產不被輕易外流。
🎯 最終成果呈現
從 Email 到驗證成功的流暢體驗
使用者在填寫完申請表單後,會收到一封精美的 HTML 郵件。郵件中的按鈕看起來像普通的連結,但背後其實藏著一段加密代碼:


- 收到郵件:點擊「立即驗證並下載」。
- 跳轉驗證:連結會帶入加密後的
id參數,例如:https://.../verify?id=MTEx。 - 輸入驗證:使用者輸入電話,系統比對
MTEx解碼後是否等於111。 - 獲取檔案:比對正確,顯示真實下載網址。
🛠 細節說明及教學
關鍵步驟:如何在 n8n 中正確轉換資料格式
在實作過程中,最容易卡關的地方就是「如何在 Expression (表達式) 中處理資料」。根據我們測試出的 JSON 結構,以下是完整的設定邏輯:
1. 掌握資料結構 (JSON)
從Google表單回覆中,當有使用者提送表單時,會透過 Webhook傳送訊息到n8n中,Webhook收到的資料長什麼樣子(如下圖)。

根據傳入的json格式發現,電話號碼藏在 body 裡的陣列中:
- 路徑:
$json.body['家長聯絡電話'][0] - 內容:
"111"
2. 使用 Base64 加密連結
在 n8n 的郵件節點中為避免明碼顯示。因此利用code節點,將電話號碼轉換成 Base64 編碼。
JavaScript
// 針對每一個進來的項目進行處理
for (const item of $input.all()) {
try {
// 根據你提供的 JSON 結構,抓取電話號碼
// 路徑是:item.json.body['家長聯絡電話'][0]
const phoneRaw = item.json.body['家長聯絡電話'][0];
if (phoneRaw) {
// 使用 Buffer 進行 Base64 加密
item.json.encodedId = Buffer.from(phoneRaw.toString()).toString('base64');
} else {
item.json.encodedId = 'no-phone-found';
}
} catch (error) {
item.json.encodedId = 'error-processing';
}
}
return $input.all();
這行程式碼做了四件事:
1. 遍歷處理:逐一校對資料
- 代碼:
for (const item of $input.all()) - 解釋: n8n 可能一次接收到多筆資料。這行指令就像是一個「輸送帶檢查員」,確保每一個進入這個節點的資料(Item)都會被依序執行相同的處理邏輯,不會漏掉任何一個人。
2. 精準定位:從複雜 JSON 中抓取目標
- 代碼:
item.json.body['家長聯絡電話'][0] - 解釋: 這是最關鍵的「導航」。
body:進入資料的主體。['家長聯絡電話']:尋找標籤名為「家長聯絡電話」的欄位(因為名稱有中文,所以必須用括號與引號包裹)。[0]:因為資料被包在陣列(Array)中,這代表抓取該欄位內的第一筆內容。
3. 安全轉換:Buffer 加密術
- 代碼:
Buffer.from(...).toString('base64') - 解釋: 這是將電話號碼「隱身」的過程並利用encodedId輸出。
- 它不是直接傳送
111,而是將其轉換為電腦二進位格式(Buffer),再轉譯成 Base64 字串。 - 優點: 這樣產生的連結
?id=MTEx看起來就像亂碼,一般使用者無法一眼看出這是電話號碼,增加了隱私保護。
- 它不是直接傳送
4. 容錯機制:預防流程當機
- 代碼:
try { ... } catch (error) { ... }及if (phoneRaw) - 解釋: 這是「保險絲」設計。
- 如果某個使用者忘了填電話,或是資料格式突然出錯,程式會回傳
no-phone-found或error-processing,而不會導致整個自動化工作流(Workflow)直接當機中斷。
- 如果某個使用者忘了填電話,或是資料格式突然出錯,程式會回傳
3. 設定 HTML 郵件內容
在 Gmail 節點或 Email 傳送節點中,切換到 HTML 模式。你可以用簡單的 <a> 標籤來包裝你的加密連結:
HTML
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; border: 1px solid #ddd; padding: 20px;"> <h2 style="color: #333;">🔒 文件下載身份驗證</h2> <p>您好,感謝您的申請。為了確保資料安全,請點擊下方按鈕驗證您的電話號碼,驗證成功後即可取得下載連結:</p> <div style="text-align: center; margin: 30px 0;"> <a href="你的webhook網址?id={{ $json.encodedId }}" style="background-color: #007bff; color: white; padding: 15px 25px; text-decoration: none; border-radius: 5px; font-weight: bold; display: inline-block;"> 立即進行驗證 </a> </div> <p style="color: #666; font-size: 12px;">此連結為專屬驗證連結,請勿將此信件轉寄給他人。</p> <hr style="border: 0; border-top: 1px solid #eee;"> <p style="color: #999; font-size: 12px;">這是系統自動發出的郵件,請勿直接回覆。</p> </div>
這樣就可以完成加密動作!後續等使用者輸入完後才是要進行驗證的動作。下次再來說明驗證的部份!
在〈“如何在 n8n 建立安全的驗證連結?Base64 加密與 Webhook 實戰教學”〉中有 1 則留言
[…] 可參考:如何在 n8n 建立安全的驗證連結?Base64 加密與 Webhook 實戰教學 […]