0x00 多點登陸概念
多點登陸,即用戶使用應用A登陸本身的帳號,以後又使用應用B登陸同一帳號,若是這時應用A的帳號通過刷新操做以後帳號就被註銷登陸,那麼這個應用對於多點登陸就是有限制的。例如咱們的微信帳號不能夠在同一移動設備同時在線。java
0x01 多點登陸原理
那麼多點登陸限制是怎麼實現的呢?安全
以上圖是根據大佬們的總結和本身的消化畫出來的。重點就是口令匹配登陸成功以後,進行判斷當前用戶是否已經登陸了。微信
若是已經登陸就須要將先登陸的用戶sessionid存放到另外一個容器中,當下一次用戶使用該sessionid進行登陸時匹配到該記錄就強制其下線(這是對安全要求極高的狀況下,也能夠選擇只是提醒說「該帳戶已於何時在哪裏登陸」)。同時也能夠對後登陸的用戶在正式登陸以前進行提醒,如「當前帳號已登陸,是否確認登陸」。session
而若是以前未登陸的狀況就直接服務端生成sessionid返回給客戶做爲這次會話的惟一標識就好。this
0x02 代碼實現
個人java很菜,只能從網上找出相關代碼:當登陸成功後,向session中放入登陸成功的帳號對象loginuser,觸發LoginListenner中的attributeAdded事件,在這個事件中,咱們判斷存放帳號和session對應關係的map中是否有當前登陸的帳號的session,若是有咱們就把該session從map中移除,同時註銷該session,而後把剛登陸的帳號和session放入map。下面是代碼:spa
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; } }
參考:.net