用戶登錄的業務流程架構設計

1、目的前端

對用戶登錄業務流程進行一個梳理,試圖從應用層角度來解決業務上曾經遇到的一些坑,提升業務的安全性,可是不可避免,流程上覆雜了一些,同時業務處理時間上會有一些損耗。nginx

2、主要流程數據庫


一、請求發送前的預處理。在對服務器發起請求以前,經過前端的處理手法,對用戶名和密碼進行一些處理,好比校驗字符串的合理性,對密碼進行hash(經常使用的也就是MD5,SHA這些,能夠百度一下),對即將提交的數據進行hash來保證網絡請求中的合法性,必定程度防止被中間人篡改數據等等。網絡請求的API同時也能夠採用https來進行輔助。安全

二、進入業務模塊前的處理。咱們沒有辦法知道發送上來的請求是不是有效的請求,可能與重複的數據發送,可能有機器人的行爲,也有多是跨過運維的撞庫的行爲,因此在進入業務模塊前,咱們要進行一些預處理,來儘可能減小一些無用的數據,在必定程度上也能夠減小一些數據庫的壓力。服務器

當服務器接收到客戶端請求以後,首先會檢查來路的ip地址是否存在於黑名單列表中,若是存在的話,這個請求就會被遺棄掉。咱們假定了這個黑名單,用以記錄咱們斷定爲有機器人登錄、試圖猜想密碼、撞庫等等異常行爲的ip。(事實上在有些團隊中,會有負責安全模塊的運維同窗或者開發同窗對全局的網絡請求進行ip過濾,能夠試圖基於nginx模塊或者其餘其餘服務器組件進行開發,力求在網絡層解決掉這個問題。)網絡

由於用戶登錄的行爲咱們沒法預知,因此我這裏採用的方案是設定了兩個機制:第一,在用戶登陸頁,校驗碼的出現是隨機的,在展現用戶登錄頁面的時候,向服務器發起一次請求,由服務器決定是否在客戶端展現校驗碼;第二,設定重複登錄的兩個閥值,當單位時間內嘗試登錄的次數到達第一個閥值時候,咱們認爲這是用戶正常的行爲,可是須要給咱們一個確認,因此咱們在客戶端輸入數據的時候,強制要求必須有驗證碼,當到達第二個閥值的時候,咱們纔會將用戶的ip或用戶名放入黑名單,在黑名單中保留一段時間。(由於公網ip是可變的,若是持久放入,可能會影響到真正的用戶。在安全要求比較高的場景中,到達閥值的時候,服務提供商會經過各類方式聯繫用戶進行確認,或者短信,或者電話,各有各的招兒吧)架構

若是這個發起請求的ip咱們斷定爲是有效的,接下來咱們要作的就是對接收到的數據進行一系列校驗以確保其合理性。例如完整性校驗、字符串校驗、特殊字符過濾,是不是replay等等,有必要話,咱們還在對其來路域名進行校驗(oauth機制和咱們這個業務不太同樣,因此也沒有更深刻的考慮),確保這個請求的合法性。運維

三、業務模塊的處理加密

進行到這一步,咱們能夠斷定這個請求是合法的,數據是可用的,接下來業務就相對比較簡單了,常規就是根據提交上來的用戶名和密碼從存儲服務器中進行檢索。須要注意的是咱們在服務器中存儲密碼的時候,對密碼進行了諸如md5(salt.md5(password))的處理,salt也是可變的,salt或者根據每次登錄成功的時間進行變動,或者根據用戶信息完整性作的hash,這樣即便被拖庫,字典造起來也是挺麻煩的一件事情,算是一種對安全上的考慮吧。spa

3、閒話

這個業務架構的設計其實也不算成熟,只是儘可能在業務層減小一些安全問題如撞庫、密碼猜想、replay,在實際應用中,根據不一樣的場景也有不一樣的處理方案,如每次登錄都會短信通知或發送驗證碼,ActiveX插件,屏幕鍵盤等等。

對於replay攻擊,見識有限,也不知道有什麼特別好的法子,這個業務設計中採用了檢查單位時間內表單數據是否提交過,若是提交過的話就不進行任何處理,處理的比較粗放。另外有一種辦法就是每一次用戶發起登錄請求以前,客戶端會向服務器請求一個一次性的token,服務器會檢查這個token的值和服務器存儲的是否一致。

我見過用對稱加密的方式來對數據包進行加密,可是這種加密方式的話,客戶端代碼一旦被反編譯,一切都是亮堂堂的,這點不如非對稱加密,可是非對稱交密又沒法保證從服務器獲取的私鑰必定可信,因此對數據包加密這個方案很差作評估,若是有了解的能夠交流一下(saintatgod@gmail.com)。

相關文章
相關標籤/搜索