web.xml中增加SessionListener
<listener> <listener-class>com.workbgm.common.listener.SessionListener</listener-class> </listener>
SessionListener类
package com.workbgm.common.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class SessionListener implements HttpSessionListener { private MySessionContext context = MySessionContext.getSessionContext(); @Override public void sessionCreated(HttpSessionEvent e) { // context.addSession(e.getSession()); } @Override public void sessionDestroyed(HttpSessionEvent e) { context.delSession(e.getSession());//只是处理session超时的情况 } }
说明:前面这一堆只是为了在session超时时,更新最新的session状态!
MySessionContenxt类
package com.workbgm.common.listener; import com.workbgm.grid.interceptor.LoginInterceptor; import com.workbgm.grid.model.vo.data.LoginUserInfo; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSession; public class MySessionContext { private static MySessionContext context; private Map<String, HttpSession> map; private MySessionContext() { map = new HashMap<>(); } public static MySessionContext getSessionContext() { if(context == null) { context = new MySessionContext(); } return context; } //添加 public synchronized void addSession(HttpSession session) { if(session!= null) { LoginUserInfo loginUserInfo = (LoginUserInfo) session.getAttribute(LoginInterceptor.SESSION_USER); if(loginUserInfo!=null) { //登录名-用户ID作为key,你可以定义你自己的 String key=loginUserInfo.getSysUser().getUsername()+"-"+loginUserInfo.getSysUser().getId(); HttpSession oldSession=this.getSession(key); if(oldSession!=null) { String newUUID= session.getAttribute(LoginInterceptor.SESSION_CSRF_TOKEN).toString(); String oldUUID = oldSession.getAttribute(LoginInterceptor.SESSION_CSRF_TOKEN).toString(); if (!newUUID.equals(oldUUID)) {//不同浏览器才处理 this.clearSession(key); } } map.put(key, session); } } } //清除 public synchronized void clearSession(String key){ HttpSession oldSession=this.getSession(key); if(oldSession!=null){ oldSession.invalidate();//让session失效 map.remove(key); } } //获取 public synchronized HttpSession getSession(String key) { if(key == null) return null; return map.get(key); } //删除 public synchronized void delSession(HttpSession session) { if(session!= null){ LoginUserInfo loginUserInfo = (LoginUserInfo) session.getAttribute(LoginInterceptor.SESSION_USER); if(loginUserInfo!=null) { String key=loginUserInfo.getSysUser().getUsername()+"-"+loginUserInfo.getSysUser().getId(); clearSession(key); } } } }
在用户登录的时候调用addSession方法,会踢掉之前登录的用户。
那么主动踢掉用户也很简单了,只需要增加一个UI界面,把MySessionContenxt的map展示出来,踢掉就调用clearSession方法就可以了,so easy!
2019年1月22日更新
______________________
MySessionContext的addSession方法做了更新,处理了没有关闭浏览器退出,无法重新登录的bug! 这里的SESSION_CSRF_TOKEN,为了防止CSRF攻击顺便处理了同一浏览器session区分的问题,其赋值是在用户登录的时候,形式如下: this.setSessionAttr(LoginInterceptor.SESSION_CSRF_TOKEN,java.util.UUID.randomUUID());