使用Map简单实现同一个账号不能两个地方同时在线

背景:框架Jfinal,使用Session保存账号信息

思路:在登录的使用获取sessionId 与user_id 加入map,每次请求接口使用拦截器验证。

1. 定义全局Map

public class UserSessionHelper {
	
	private static ConcurrentHashMap<Integer, String> sessionIDMap = new ConcurrentHashMap<>();
	
	public static Map<Integer, String> getSessionIDMap(){
		return sessionIDMap;
	}
	
	public static void setSessionIDMap(Map<Integer, String> sessionIDMap){
		sessionIDMap.putAll(sessionIDMap);
	}

	
	
}

2. 生成一个单账号拦截类 

public class SingleUserInterceptor implements Interceptor{

	@Override
	public void intercept(Invocation inv) {
		Controller controller = inv.getController();

		HttpServletRequest request = inv.getController().getRequest();
		
		UserInfo userInfo = (UserInfo) request.getSession().getAttribute(LoginUtil.SESSION_USER_TAG);
		if (userInfo != null) {
			String sessionId = UserSessionHelper.getSessionIDMap().get(userInfo.getId());
			if (sessionId != null && sessionId.equals(request.getSession().getId())) {
				inv.invoke();
			} else {
				// 判断如果是异步请求,设置响应头 sessionstatus为timeout,自动跳转,否则重定向
				if (request.getHeader("x-requested-with") != null
						&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
					System.out.println("同账号多人登录  user.id >>>>>>>>>>>>>>"+userInfo.getId());
					request.getSession().invalidate();
					
					request.getSession().setAttribute(LoginUtil.SESSION_USER_TAG, null);
					request.getSession().setAttribute("loginflag", null);
					request.getSession().setAttribute("casLogoutUrl", null);
					controller.redirect("/login/logout");
				} else {
					try {
						request.getSession().invalidate();
						
						request.getSession().setAttribute(LoginUtil.SESSION_USER_TAG, null);
						request.getSession().setAttribute("loginflag", null);
						request.getSession().setAttribute("casLogoutUrl", null);
						controller.redirect("/login/logout");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}

	}


}

 3. 在Login中 存入Map

//20220714 add 为了同一个账号只能登录一人
							String sessionId = getSession().getId();
							if(!UserSessionHelper.getSessionIDMap().containsKey(user.getId())){//不存在,第一个人login
								UserSessionHelper.getSessionIDMap().put(user.getId(), sessionId);
							}else if(UserSessionHelper.getSessionIDMap().containsKey(user.getId())&& 
									!StringUtils.equals(sessionId, UserSessionHelper.getSessionIDMap().get(user.getId()))){//该账号存在但是sessionID不一致
								UserSessionHelper.getSessionIDMap().remove(user.getId());
								UserSessionHelper.getSessionIDMap().put(user.getId(), sessionId);
							}

4. 第二步的java类加入config

/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		
		me.addGlobalActionInterceptor(new SingleUserInterceptor());
	}

这样, 如果 两个A账号先登录, A1账号再次登录就会将A的session清除,A在请求其他接口的时候,被拦截器拦住,跳转到登出接口

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值