情境 server可以定時為用戶推送一些資料,現在需要用戶輸入郵箱,經過驗證後將其納入發送列表以便向此郵箱提供服務。 沒什麼新穎的技術,事先也沒有查閱相關資料,只是一些搭建簡易驗證流程的想法。 如果有更靠譜的或者更簡單的也可以comment。 關於驗證流程 郵箱地址有效性驗證 這個問題應該困擾過很多 ...
情境
server可以定時為用戶推送一些資料,現在需要用戶輸入郵箱,經過驗證後將其納入發送列表以便向此郵箱提供服務。
沒什麼新穎的技術,事先也沒有查閱相關資料,只是一些搭建簡易驗證流程的想法。
如果有更靠譜的或者更簡單的也可以comment。
關於驗證流程
郵箱地址有效性驗證
這個問題應該困擾過很多人,一般情況下的解決方案是使用正則表達式去匹配郵箱格式。
但是我這種不精通Regex的人大概不想這麼做,所以使用了最為暴力的方法:
Just send them an email already.
出自文章:Stop Validating Email Addresses With Regex,(義正言辭地偷懶,哈哈,畢竟最原始的方法才是最好用的,郵箱的各種奇葩合法格式很難匹配全吧,容易誤傷。
這樣就自然而然地引出了下麵一個問題,我們需要給用戶一個鏈接訪問server,server驗證此鏈接所帶param的特征去激活這個郵箱。
通過鏈接激活相應郵箱
0x0 Hash
用一個專門存放待驗證郵箱的資料庫表。
首先用戶填入了郵箱[email protected]
,server計算其hash之後將其存入表中:
{
"mailbox": "[email protected]",
"hash": "7DAF6C79D4802916D83F6266E24850AF"
}
向用戶發送鏈接:
https://yourserver.com/api/v1/validate?hash=7DAF6C79D4802916D83F6266E24850AF
用戶點擊後,server用這個hash把待驗證的email地址查出來,挪到服務列表裡。
0x1 Encrypt -> Derypt (or Encode -> Decode)
這種方式就是不使用一個中間資料庫表,直接用加密函數&密鑰去加密郵箱地址,然後發給這個郵箱:
https://yourserver.com/api/v1/validate?secret=s7dz5rt3y1u6ijkl7mn8b9hgvj96frrnagpkfg93gs51
(以上密文是臉滾鍵盤生成的,僅供示例。
用戶點擊之後server再將密文用秘鑰解密得到郵箱地址,將其加入服務列表。
關於驗證時機
先驗證,後服務
使用一些別的網站的時候,感覺大多數都是用的這種,畢竟使用郵箱註冊的賬號必須要求賬號名有效,上面設想的兩種流程也屬於驗證後再服務。
先服務,後驗證
對於一些對郵箱地址有效性要求並不那麼高的服務來說,比如訂閱資訊等,不需要用戶立即去驗證郵箱就可立即提供一段時間的服務。
這樣只需要一個表,在表中設置一個狀態validated
即可,也便於用戶退訂服務的狀態更改,如果用hash法,只需要直接新建:
{
"mailbox": "[email protected]",
"hash": "7DAF6C79D4802916D83F6266E24850AF",
"validated": false
}
驗證成功後再將validated
置true
。
加密解密(編碼解碼)的話就存:
{
"mailbox": "[email protected]",
"validated": false
}
不過這樣好像就跟不需要預先存郵箱地址的初衷衝突了,不過考慮到這種服務方式只需要一張表,也就沒那麼虧了。
那麼超期仍未驗證的郵箱怎麼辦呢,我們可以跑一個Batch定期檢查,把逾期的記錄從服務表中移除。
同樣,先驗證後服務的待驗證列表也可以用這種方式移除逾期未驗證的郵箱,但是加解密(編解碼)的方式因為沒有中間狀態所以也沒有辦法判斷是否逾期了。
如果想獲得簡單且更加靈活的驗證方式也可以嘗試組合本文中的各種流程。