WEB_Rember Me(自動登入) 的幾種實現思路
阿新 • • 發佈:2019-02-05
本文討論幾種記住我功能的實現方式。
原理:使用者登入後,服務端為使用者生成一個Token,並放入客戶端Cookie中。下次使用者登入,服務端驗證Cookie中的Token並自動登入。
password:使用者密碼。 expiryTime:Token的失效時間,以毫秒錶示。
該方法生成的Token不需要持久化,每次生成時失效時間不同,可保證Token不同(也可以在Token中增加一些變數,如系統配置的key)。使用者第一次登陸時生成Token;第二次開啟系統時,根據CookieValue中username查詢資料庫,並重新生成Token,驗證使用者提交Token是否正確,如果正確成功登入系統,如果不正確,調整到登陸頁面。
存在安全問題。當用戶Cookie被竊取(HttpOnly增加安全性),任何使用者都可以在Token失效之前登入。發現被盜用,可以修改password來使Token失效,或者系統在使用者每次登入系統時都重新生成Token。
缺點:由於Token沒有持久化,所以需要從已知的變數(如username、password、expiryTime)重新生成來驗證,password即使加密放入前臺,也不是一個好的解決方法。縱然不使用password,也需要其他變數來保證Token的可靠性。
Token的生成規則可以自定義,只要保證每次username的Token不一樣就可,例如採用16位隨機數(如Java的SecureRandom)。規則同上面類似,只是將Token與使用者資訊解耦。但是安全問題依舊存在。
情況二、同用戶不同瀏覽器訪問系統
情況三、Cookie被盜
安全問題依然存在。當然,可以考慮使用者訪問等級,如使用者名稱密碼登入級別最高,而對於Token記住我登入次之,對於一些重要的業務操作時(如支付),還是需要進行使用者身份認證。
還可以考慮使用者IP,但現在移動使用者,經常切換WiFi和網路,所以IP也會發生變化。例如手機銀行(如招行客戶端)切換網路後,需要重新登入,提高安全性。
還可以考慮,使用者常用IP、城市等安全策略。
還有Shiro也實現了該記住我功能,但是本人沒有使用過,等退後學習了再來更新。
- 簡單的Token生成方法
password:使用者密碼。 expiryTime:Token的失效時間,以毫秒錶示。
該方法生成的Token不需要持久化,每次生成時失效時間不同,可保證Token不同(也可以在Token中增加一些變數,如系統配置的key)。使用者第一次登陸時生成Token;第二次開啟系統時,根據CookieValue中username查詢資料庫,並重新生成Token,驗證使用者提交Token是否正確,如果正確成功登入系統,如果不正確,調整到登陸頁面。
存在安全問題。當用戶Cookie被竊取(HttpOnly增加安全性),任何使用者都可以在Token失效之前登入。發現被盜用,可以修改password來使Token失效,或者系統在使用者每次登入系統時都重新生成Token。
缺點:由於Token沒有持久化,所以需要從已知的變數(如username、password、expiryTime)重新生成來驗證,password即使加密放入前臺,也不是一個好的解決方法。縱然不使用password,也需要其他變數來保證Token的可靠性。
- 持久化的Token生成方法
Token的生成規則可以自定義,只要保證每次username的Token不一樣就可,例如採用16位隨機數(如Java的SecureRandom)。規則同上面類似,只是將Token與使用者資訊解耦。但是安全問題依舊存在。
- 持久化Token生成方法並驗證Cookie是否被竊取
步驟 | 使用者A瀏覽器 |
1 | A登入成功,series=seriesA,token=tokenA |
2 | 在Token失效之前該瀏覽器訪問系統,合法,生成series=seriesA,token=tokenB。 |
3 | Token失效,或者使用者重新登入,生成series=seriesB,token=tokenC |
步驟 | 使用者A瀏覽器X | 使用者A瀏覽器Y |
1 | 瀏覽器X登入成功,series=seriesA,token=tokenA | |
2 | 瀏覽器Y訪問,無series資訊,使用者重新登入,series=seriesB,token=tokenB | |
3 | 瀏覽器X再次問題,seriesA失效,需要重新登入 |
步驟 | 使用者A | 黑客B |
1 | A登入成功,生成series=seriesA,token=tokenA | |
2 | 盜取A Cookie,使用series=seriesA,token=tokenA登入系統成功,重新生成series=seriesA,token=tokenB | |
3 | A再次訪問,發現serieA相同,但是Token不同,提醒使用者Cookie被盜 |