程序員過關斬將--少年派登錄安全的奇幻遐想
“據說,這篇也是快餐,完全符合年輕人口味
說到登錄,無人不知無人不曉。每一個有用戶體系的相關系統都會有登錄的入口,登錄是為了確認操作人的正確性。說到登錄安全,其實是一個很偉大的命題,不過常用的手段也不過爾爾。
避免明文
這個設計到用戶憑證信息的表設計,切記避免明文存儲用戶的密碼信息。還記得以前很多大廠的密碼泄露事件嗎?
在數據表的設計中,除了用戶密碼的摘要列之外,需要添加所謂的“salt”列,其實是隨機生成的一個字符串,用于和用戶密碼的摘要聯合生成最終的摘要。
loginName | salt | pwd |
---|---|---|
182xxxxxxxx | 隨機字符串 | 散列值 |
182xxxxxxxx | 隨機字符串 | 散列值 |
如果非要寫一個過程的話:
- 當用戶首次注冊的時候,系統隨機生成salt,然后和密碼按照規則拼接成一個字符串,然后求散列值,并存儲在pwd列中
- 客戶端請求登陸接口,上傳用戶的賬號和密碼,這里的密碼推薦md5的摘要(js也可以生成md5)
- 服務端接收到請求,根據用戶的賬號查詢對應的salt
- 把上傳的密碼和salt根據規則拼接,然后生成摘要
- 把上一步生成的摘要和數據庫的pwd進行對比,相同則登錄成功,不同則登錄失敗
為什么非要加入salt呢?有了salt不僅可以加大黑客破解的難度,而且同樣密碼的用戶存儲的pwd列也不相同,在用戶信息安全性上又提高了一點。
驗證碼
驗證碼是一種比較廉價的但是很有效的防止別人亂搞的手段,它通過一種只有真人才能識別的防偽手段來阻止危險。
image
以上是12306的登錄界面,看驗證碼的方式,是不是已經騷到了極點。如果你的登錄接口不希望別人暴力破解的話,驗證碼是必須的。
對于普通的網站,驗證碼程序其實可以做的很簡單就足夠用了,就像以下
image
用到的技術是服務端把驗證碼的內容繪制在一張帶有紋路的圖片上,把碼的內容存儲在一個地方,并分配一個key,把這個key返回客戶端,當客戶端登錄的時候攜帶者這個key和用戶填入的驗證碼內容來確定驗證碼是否正確。
“我曾經看過有人把驗證碼的校驗放到客戶端,要記住,客戶端其實是無安全可言的,哪怕是那些做了混淆的App。
手機驗證碼
目前幾乎所有的系統都支持手機驗證碼登錄,為什么這么普及是有原因的。
- 首先,這種方式便捷,用戶無需記住密碼,試想一下,用戶要記住自己常用的幾十個網站密碼是很難的,而且手機現在幾乎都不離身
- 其次,手機驗證碼方式安全系數比較高,因為手機號現在都采用了實名制,手機號被盜的可能性比較小,而且現在的手機都有指紋鎖,就算手機丟了也不怕
- 最后,系統都采用手機號登錄,可以高效的拉進和用戶的距離,而且也有利于國家的監管工作,畢竟根據手機號就可以追蹤到用戶的所有信息了
設備號
登錄的時候把當前設備的標識上傳到服務端進行識別,我覺得對于登錄來說很重要。為什么呢?
在現在App漫天飛的時代,在App上是要實現自動登錄的,換句話說,用戶登錄過一次這個App,當用戶下次打開的時候,需要實現自動登錄,這在用戶體驗上會比每次都登錄好很多。但是這就面臨著一個問題:需要把用戶登錄的憑證保存在本地,切換到瀏覽器中,這些憑證信息可能會保存在Cookie中或者local storage中,當然憑證肯定是要加密的。我們要保證的是這些憑證就算是被黑客知道了,也不能正常登錄。
那怎么才能保證呢?答案是設備。在用戶的登錄請求中一定要上傳設備號(瀏覽器也可以用js生成的),服務端存儲著用戶的有效設備列表,當然這個有效設備需要產品經理給出明確的定義,比如最常見的:登錄過5次的設備。當然說到設備還有一個主設備的概念,至于怎么樣才能定義主設備,也是需要產品方給出定義的,像最常見的:手機端是主設備。像微信現在登錄pc端是需要手機端掃碼的,切換到業務,可以看做需要主設備確認的請求才能執行。
安全設備概念在多點登錄的場景下非常有用,尤其是需要互踢的需求下。
登錄時間
服務端一定要記住用戶最后一次的登錄時間,在很多情況下需要記住用戶在某個設備上的最后登錄時間。這樣做不止是為了記錄分析用戶的登錄行為,還可以分析長期未登錄的用戶,使他的登錄憑據失效,強制他重新登錄。
HTTPS
雖然一個證書每幾個錢,但是https起到的作用在安全性上還是很大的。本質上它采用的也是加密算法,比http要耗費cpu,傳輸速度上要慢一些。但是它可以有效的防止中間人劫持,防止用戶信息外漏,而且可以防止被釣魚網站攻擊,有效識別網站真實身份,像其他的有利于SEO,地址欄出現安全鎖等就不說了。
寫在最后
以上所說只是一些最常見的手段,除此之外,比如IP黑名單機制,限流機制等都可以加固登錄的安全。
本文轉載自微信公眾號「架構師修行之路 」,可以通過以下二維碼關注。轉載本文請聯系架構師修行之路 公眾號。