解决同一用户同时登录的方案

最近着手解决同一用户同时登录的问题,记录一下解决方案

要求:

1.A用户已登录系统

2.A用户再次登录,踢掉第一次登录的用户

上网查阅了不少帖子,没有找到既好用又简单的方法。

只能自己琢磨了,想了2种场景的方案。

1.如果不需要分布式部署,方案很简单:

定义一个存放用户session的全局静态Map<用户id,session对象>。

用户登录时,

如果发现map中已存在用户的session,则把map中的session取出来,调用session.invalidate();使session失效。

把当前session放入Map<用户id,session对象>中,

HttpSession s = request.getSession();
if(map.containsKey(userid)){
    HttpSession session = (HttpSession)map.get(userid);
    session.invalidate();
}
map.put(userid, s);


2.分布式部署环境,session在多个应用共享,但是各应用之间的全局静态Map<用户id,session对象>无法共享,因此上面的方案不可行。

第一种思路,把session存放在各应用都可以获取的地方,考虑持久化,但是HttpSession本身不是序列化的,不能把它持久化。Tomcat提供了对session的持久化。但是我在开发时使用的是tomcat,发布时却要用jboss,因为使用的应用服务器是不确定的,因此无法采用这种方案。

第二种思路,既然很难持久化session,那就不去做。场景1的方案是在用户第二次登录时,主动找到第一次的session,然后使它失效,但现在的问题是很难取到第一次的session,因为它没有被持久化。

那就换一种思路:做一个filter拦截所有请求(除了不需要验证用户是否已登录的请求,如:登录),在filter中验证session是否有效。如果无效,则使session失效。如何判断session是否有效呢?在登录时,给session中设置一个标记,

LoginController.java

session.setAttribute(CurrentThreadContext.CURR_USER_ID, userName);
session.setAttribute(LoginConstant.SESSION_USER_CODE, random);
我这里的random是一个随机数,同时把random持久化,比如存入数据库,或者文件,缓存等,我这里暂时存在了全局变量里

LoginConstant.sessionMap.put(userName, random);





filter验证session是否有效,对比A用户session中的random和持久化的random,如果相同,则有效,否则无效,使session失效。

LoginFilter.java

HttpSession session = httpRequest.getSession(false);
            if (session != null) {
                String userName = (String) session.getAttribute(CurrentThreadContext.CURR_USER_ID);
                String sessionUserCode = (String)session.getAttribute(LoginConstant.SESSION_USER_CODE);
                
                if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(sessionUserCode) || !sessionUserCode.equals(LoginConstant.sessionMap.get(userName))){
                    //session中用户名为空 或 session验证码为空 或 验证码不正确,销毁session                  
                    session.invalidate();//使session失效
                }
            }
好了,验证一下,

1.PC1使用A登录,session中存的random=1234,持久化的random=1234,发送请求时,session有效。

2.PC2使用A登录,session中存的random=6789,持久化的random=6789,发送请求时,session有效。

3.PC1发送请求,session中的random=1234,持久化的random=6789,session无效,session.invalidate();//使session失效,返回登录页面。

4.PC2发送请求,session有效。

ok。这里需要的就是加一个filter过滤请求。

如果有什么问题或者好的方案,请拍砖交流,共同学习




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值