天天看点

java实现单用户登录原理

为了系统的安全性,很多网站都实现单用户登录,下面我们来探讨一下它的实现原理:

第一步:

public class SessionListener implements HttpSessionListener{
	public static Map<Long, String> LOGIN_USER_MAP = new HashMap<Long, String>();//登入用户
	public static Map<Long, String> LOGOUT_USER_MAP = new HashMap<Long, String>();//逼下线用户
	//session创建
	@Override
	public void sessionCreated(HttpSessionEvent event) {
	}
	//session销毁
	@Override
	public void sessionDestroyed(HttpSessionEvent event) {
		HttpSession session = event.getSession();
		User user = (User) session.getAttribute(Common.LOGIN_USER);
		if(user != null){
			LOGIN_USER_MAP.remove(user.getEid());
		}
	}
}
           

创建session监听器,监听session的事件,同时我们创建两个Map,用来存储用户的ID和sessionId。

第二步:

//登录成功后
session.setAttribute(Common.LOGIN_USER, dbUser);
String sessionId = session.getId();
if(SessionListener.LOGIN_USER_MAP.containsKey(dbUser.getEid())){//存在用户
    if(!sessionId.equalsIgnoreCase(SessionListener.LOGIN_USER_MAP.get(dbUser.getEid()))){//判断是否相同的sessionID
	SessionListener.LOGOUT_USER_MAP.put(dbUser.getEid(), SessionListener.LOGIN_USER_MAP.get(dbUser.getEid()));
	SessionListener.LOGIN_USER_MAP.put(dbUser.getEid(), sessionId);
    }
}else{
    SessionListener.LOGIN_USER_MAP.put(dbUser.getEid(), sessionId);
}
result = "redirect:/common/homepage/index.action";
           

登录成功后我们拿到登录后的用户ID,查找系统里该用户是否已经登录了,如果没有登录则保存到LOGIN_USER_MAP里,如果已经登录,则判断sessionID是否与之前登录的session相同,若不相同,需要把之前的session记录下来。

第三步:

public class LoginInterceptor implements HandlerInterceptor{
	//返回值:表示我们是否需要将当前的请求拦截下来,返回false请求被拦截下来
	//handler:表示被拦截请求的目标对象
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute(Common.LOGIN_USER);
		if(user == null){
			response.sendRedirect(request.getContextPath() + "/common/login/index.action");
			return false;
		}
		String sessionId = request.getSession().getId();
		if(SessionListener.LOGOUT_USER_MAP.containsValue(sessionId)){//判断当前用户sessionID是否存在逼下线列表里
			SessionListener.LOGOUT_USER_MAP.remove(user.getEid(), sessionId);
			response.sendRedirect(request.getContextPath() + "/common/login/index.action?message=1");
			return false;
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		//通过modelandview可以改变将要跳转的页面   
	}
	//请求要结束的时候调用,主要是进行数据的销毁,流的关闭
	//统一异常处理,统一日志处理
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
	}
}
           

在登录拦截器里做判断,判断当前用户sessionID是否存在逼下线列表里,若存在,则拦截下来。

感兴趣的朋友可以关注微信公众号(会定时推送新的知识):

java实现单用户登录原理

继续阅读