本文討論幾種“記住我”功能的實(shí)現(xiàn)方式。
原理:用戶登錄后,服務(wù)端為用戶生成一個(gè)Token,并放入客戶端Cookie中。下次用戶登錄,服務(wù)端驗(yàn)證Cookie中的Token并自動(dòng)登錄。
- 簡(jiǎn)單的Token生成方法
Token=MD5Hex(username+分隔符+expiryTime+分隔符+password)
CookieValue=Base64(username+分隔符+expiryTime+分隔符+Token)
username:用戶名。
password:用戶密碼。
expiryTime:Token的失效時(shí)間,以毫秒表示。
該方法生成的Token不需要持久化,每次生成時(shí)失效時(shí)間不同,可保證Token不同(也可以在Token中增加一些變量,如系統(tǒng)配置的key)。
用戶第一次登陸時(shí)生成Token;
第二次打開系統(tǒng)時(shí),根據(jù)CookieValue中username查詢數(shù)據(jù)庫,并重新生成Token,驗(yàn)證用戶提交Token是否正確,如果正確成功登入系統(tǒng),如果不正確,調(diào)整到登陸頁面。
存在安全問題。
當(dāng)用戶Cookie被竊?。℉ttpOnly增加安全性),任何用戶都可以在Token失效之前登錄。發(fā)現(xiàn)被盜用,可以修改password來使Token失效,或者系統(tǒng)在用戶每次登入系統(tǒng)時(shí)都重新生成Token。缺點(diǎn):由于Token沒有持久化,所以需要從已知的變量(如username、password、expiryTime)重新生成來驗(yàn)證,password即使加密放入前臺(tái),也不是一個(gè)好的解決方法??v然不使用password,也需要其他變量來保證Token的可靠性。
持久化的Token生成方法
Token的生成規(guī)則可以自定義,只要保證每次username的Token不一樣就可,例如采用16位隨機(jī)數(shù)(如Java的SecureRandom)。規(guī)則同上面類似,只是將Token與用戶信息解耦。但是安全問題依舊存在。
持久化Token生成方法并驗(yàn)證Cookie是否被竊取
Token:隨機(jī)生成策略,只要保證username唯一性。
series:登錄序列號(hào),隨機(jī)生成策略。用戶輸入用戶名和密碼登錄時(shí),該值重新生成。使用remember-me功能,該值保持不變,重新生成Token。
expiryTime:Token過期時(shí)間。
1)每次用戶選擇記住我并登錄后,都重新隨機(jī)生成series、Token,保存到數(shù)據(jù)庫和前端Cookie中。
2)下一次用戶再次訪問系統(tǒng),
情況一:前臺(tái)Cookie中保存的series值在數(shù)據(jù)庫中不存在,跳轉(zhuǎn)到登錄頁面。
情況二:series、Token與數(shù)據(jù)庫中一致,則仍為合法用戶,并保持series不變,重新隨機(jī)生成Token,覆蓋前臺(tái)Cookie值。
情況三:series在數(shù)據(jù)庫中存在,但Token不一致,說明Cookie被竊取。
情況一、同用戶相同瀏覽器訪問系統(tǒng)

情況二、同用戶不同瀏覽器訪問系統(tǒng)

情況三、Cookie被盜

安全問題依然存在。
a. 可以考慮用戶訪問等級(jí),如用戶名密碼登錄級(jí)別最高,而對(duì)于Token記住我登錄次之,對(duì)于一些重要的業(yè)務(wù)操作時(shí)(如支付),還是需要進(jìn)行用戶身份認(rèn)證。
b. 還可以考慮用戶IP,但現(xiàn)在移動(dòng)用戶,經(jīng)常切換WiFi和網(wǎng)絡(luò),所以IP也會(huì)發(fā)生變化。例如手機(jī)銀行(如招行客戶端)切換網(wǎng)絡(luò)后,需要重新登錄,提高安全性。
c. 還可以考慮,用戶常用IP、城市等安全策略。