每封信底部都要有「退訂」。最直覺的寫法是 /unsubscribe?email=someone@x.com&token=…——網址帶著 email 和一個簽章。但這個設計有兩個藏在細節裡的問題。
一、email 攤在網址上。網址會被記進伺服器日誌、瀏覽器歷史、referrer,甚至被轉寄——等於把訂閱者的信箱到處留痕。
二、退得掉別人。如果 token 是用 email 算出來的固定簽章,它永不失效;任何拿到那條連結的人(轉寄、側錄、日誌)都能隨時退訂那個人。
不可猜的隨機 token。每個訂閱者發一組跟 email 無關的隨機 token,存在資料庫。退訂網址只帶 token、完全不帶 email——退不了別人,也不外洩信箱。
兩段式:GET 只確認、POST 才退訂。很多信箱與防毒會自動「點開」信裡的連結去掃描;如果 GET 就退訂,會被這些掃描器誤觸。所以 GET 只回一個「確定要退訂嗎」的頁面,按下按鈕送出的 POST 才真的改狀態。
// 退訂只認隨機 token;GET 安全、POST 才有副作用 GET /unsubscribe?t=<random> → 顯示「確認退訂」頁(不改狀態) POST /unsubscribe { t } → 查到訂閱者 → 設為已退訂 + 通知站長 // token 產生:與 email 沒有任何可推導關係 unsubToken = crypto.randomBytes(32).toString("hex"); // 唯一、索引
退訂連結是少數「陌生人手上就有」的入口。把 email 從網址拿掉、用不可猜的隨機 token、再用「GET 確認 / POST 執行」擋掉自動掃描——退訂就從「誰都能退掉誰」變成「只有本人點得動」。





