如何在 n8n 建立安全的驗證連結?Base64 加密與 Webhook 實戰教學

🔒 為什麼我們需要「帶參數」的驗證連結?

打造一個既方便又具備初步安全性的下載流程

在設計「自動化考題下載」或「資料索取」系統時,我們常遇到一個難題:如何確認點擊連結的人真的是本人?

如果直接把下載網址寄給使用者,連結可能會被隨意轉傳。透過在 Email 連結中加入一個「加密過的 ID 或電話」,當使用者點擊後,我們可以先引導他到一個驗證頁面(例如輸入電話比對)。這不僅提升了專業感,也能有效保護你的數位資產不被輕易外流。

🎯 最終成果呈現

從 Email 到驗證成功的流暢體驗

使用者在填寫完申請表單後,會收到一封精美的 HTML 郵件。郵件中的按鈕看起來像普通的連結,但背後其實藏著一段加密代碼:

  1. 收到郵件:點擊「立即驗證並下載」。
  2. 跳轉驗證:連結會帶入加密後的 id 參數,例如:https://.../verify?id=MTEx
  3. 輸入驗證:使用者輸入電話,系統比對 MTEx 解碼後是否等於 111
  4. 獲取檔案:比對正確,顯示真實下載網址。

🛠 細節說明及教學

關鍵步驟:如何在 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-founderror-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 則留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *