1. 概述
傳統的單體應用中,用戶是否登錄,通常是通過從Tomcat容器的session中獲取登錄用戶信息判斷的。
但在分布式的應用中,通常負載均衡了多台Tomcat,每台Tomcat都有自己獨立的session,用戶的每次請求都可能到達不同的Tomcat,因此可能會出現需要登錄多次或者登錄無效的情況出現。
為了解決這個問題,就需要使用一個緩存中間件,將登錄用戶的信息存入這個緩存中間件,所有的Tomcat都從緩存中間件中獲取登錄用戶信息,從而判斷登錄狀態。
Redis就是一個很好用的緩存中間件,接下來我們就來聊聊分布式應用該如何實現用戶登錄的邏輯。
2. 單體應用的用戶登錄
傳統的單體應用,通常只有一個Tomcat。
用戶提交登錄信息時,后台會根據用戶登錄名,得到用戶信息,然后比對密碼,如果正確,則將用戶信息放入Tomcat的session中。
用戶請求需要登錄的接口時,先從Tomcat的session中得到用戶信息,如果用戶信息是null,則接口無法訪問,提示用戶登錄。如果用戶信息不為null,則使用用戶信息完成接口邏輯。
3.分布式應用的用戶登錄
3.1 方案一:允許用戶異地登錄
用戶提交登錄信息時,后台根據用戶登錄名,得到用戶信息,然后比對密碼,如果正確,則生成一個隨機數。
以這個隨機數為key,用戶信息為value,存入redis。
在cookie中存入一個固定值的key,例如:mySessionId,value為這個隨機數。
用戶請求需要登錄的接口時,先從cookie中拿到隨機數,然后以隨機數為key,從redis中得到用戶信息,如果用戶信息不為null,則表示用戶已登錄。
用戶注銷登錄時,將cookie中的隨機數和redis中的用戶信息都清空。
3.2 方案二:不允許用戶異地登錄(以新登錄的為准)
用戶提交登錄信息時,后台根據用戶登錄名,得到用戶信息,然后比對密碼,如果正確,則生成一個隨機數。
將這個隨機數放入用戶信息中,在cookie中存入一個固定值的key,例如:curUser,value是脫敏后的用戶信息。
以用戶ID為key,這個隨機數為value,存入redis。
用戶請求需要登錄的接口時,先從cookie中拿到用戶信息,然后以用戶信息中的用戶ID為key,從redis中得到隨機數。
如果redis中隨機數不存在,則表示沒有登錄,如果存在,使用redis中得到的隨機數與cookie中用戶信息中的隨機數做對比,如果不一致,則表示用戶在其他地方登錄,需要重新登錄。
用戶注銷登錄時,將cookie中的用戶信息和redis中的隨機數都清空。
4.綜述
今天簡單聊了一下使用redis實現分布式會話,希望能對大家的工作有所幫助。
歡迎大家多多評論交流,共同成長。
關注追風人聊Java,每天更新Java干貨。