0x00 多點登錄概念
多點登錄,即用戶使用應用A登錄自己的賬號,之后又使用應用B登錄同一賬號,如果這時應用A的賬號經過刷新操作之后賬號就被注銷登錄,那么這個應用對於多點登錄就是有限制的。例如我們的微信賬號不可以在同一移動設備同時在線。
0x01 多點登錄原理
那么多點登錄限制是怎么實現的呢?
以上圖是根據大佬們的總結和自己的消化畫出來的。重點就是口令匹配登錄成功之后,進行判斷當前用戶是否已經登錄了。
如果已經登錄就需要將先登錄的用戶sessionid存放到另一個容器中,當下一次用戶使用該sessionid進行登錄時匹配到該記錄就強制其下線(這是對安全要求極高的情況下,也可以選擇只是提醒說“該賬戶已於什么時候在哪里登錄”)。同時也可以對后登錄的用戶在正式登錄之前進行提醒,如“當前賬號已登錄,是否確認登錄”。
而如果之前未登錄的情況就直接服務端生成sessionid返回給客戶作為此次會話的唯一標識就好。
0x02 代碼實現
我的java很菜,只能從網上找出相關代碼:當登錄成功后,向session中放入登錄成功的賬號對象loginuser,觸發LoginListenner中的attributeAdded事件,在這個事件中,我們判斷存放賬號和session對應關系的map中是否有當前登錄的賬號的session,如果有我們就把該session從map中移除,同時注銷該session,然后把剛登錄的賬號和session放入map。下面是代碼:
public class LoginListenner implements HttpSessionAttributeListener { /** * 用於存放賬號和session對應關系的map */ private Map<string, httpsession=""> map = new HashMap<string, httpsession="">(); /** * 當向session中放入數據觸發 */ public void attributeAdded(HttpSessionBindingEvent event) { String name = event.getName(); //用戶已登錄 if (name.equals("loginuser")) { User user = (User) event.getValue(); if (map.get(user.getUserName()) != null) { HttpSession session = map.get(user.getUserName()); session.removeAttribute(user.getUserName()); session.invalidate(); } map.put(user.getUserName(), event.getSession()); } } /** * 當向session中移除數據觸發 */ public void attributeRemoved(HttpSessionBindingEvent event) { String name = event.getName(); if (name.equals("loginuser")) { User user = (User) event.getValue(); map.remove(user.getUserName()); } } public void attributeReplaced(HttpSessionBindingEvent event) { } public Map<string, httpsession=""> getMap() { return map; } public void setMap(Map<string, httpsession=""> map) { this.map = map; } }
參考: