一账户一设备登录,session状态监听以及js检测浏览器TAB关闭和浏览器关闭

初到一个公司,在他们现有系统基础上(原登录只用了cookie验证)加做一个账户登录权限–>一个账户只能一处登录,和管理员可以查看各个账号的登录状况,是否在线。
根据需求和现有系统的基础上(改动较少的情况下)登录状态修改了对cookie进行操作,和增加session的操作。一账户登录引入了redis非关系型数据库。

一账户一设备登录

在登录的时候增加一个cookie和redis的set值
cookie值的设置规则:用户ID:时间戳 处于安全性可以选择jwt或者aes进行加解密,redis的存入规则key使用用户ID,value存入当前用户对象并增加属性登录时间戳(和cookie一致)
增加拦截器,对操作进行判断,取出cookie,使用id去reids中查询,进行时间戳的对比,一致证明是同一用户操作,不一致证明其他处登录,重新跳转到登录页面即可。

//设置cookie
long longTime = System.currentTimeMillis();
String cookieValue = id+":"+longTime;
Cookie cookie = new Cookie(name, null);
cookie.setPath(path);
cookie.setMaxAge(maxAge);
if(StringUtils.isNotEmpty(domain)){
	cookie.setDomain(domain);
}
try {
	cookie.setValue(URLEncoder.encode(value, "utf-8"));
} catch (UnsupportedEncodingException e) {
	e.printStackTrace();
}
response.addCookie(cookie);

//redis的设置
...
jedis.set(key, value);
...

配置拦截器再spring的配置文件中

<mvc:interceptor>
		<mvc:mapping path="/vender/**" />
		<mvc:mapping path="/venderBigScreen/**" />
		<mvc:exclude-mapping path="/venderBigScreen/systemLogin"/>
		<mvc:exclude-mapping path="/venderBigScreen/systemLogin#"/>
		<bean  class="com.jeeplus.common.servlet.HasUserLoginInteceptor" />
	</mvc:interceptor>

在拦截器中获取cookie和redis的值进行判断,代码略

session监听以及浏览器监听
考虑到登录状态,用的session存入,sesison存入的时候我把sessionid也存放到value中了,并进行session监听,主要系统中的servlet的session是否被第三方托管,本系统使用的shrio
shiro配置文件中配置监听器

 <!-- 自定义session监听器 -->  
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
        <property name="sessionListeners" ref="sessionListener" />  
    </bean>  
    <bean id="sessionListener" class="org.hyc.shiro.session.MySessionListener"/>  

编写自己的监听器,用于监听会话的创建,过期,以及停止事件

public class MySessionListener implements SessionListener {
    @Override
    public void onStart(Session session) {//会话创建时触发
        System.out.println("会话创建:" + session.getId());
        String str = (String) session.getAttribute("vender_login_flag");  //获取session的值
		if(StringUtils.isNotEmpty(str)){
			String[] arr = str.split(":");//原来session值存入规则 id:sessionid
			if(arr[1].length()>8&&arr[2].equals(session.getId())){
				// TODO  更改用户的登录状态
			}
		}
    }
    @Override
    public void onExpiration(Session session) {//会话过期时触发
        System.out.println("会话过期:" + session.getId());
    }
    @Override
    public void onStop(Session session) {//退出/会话过期时触发
        System.out.println("会话停止:" + session.getId());
    }  
 }

但是又考虑到session监听失效可能不及时,因为当我们的浏览器关闭时只是客户端的sessionid失效了,到那时服务器端的session(过期时间)仍然存在,session 超时后会被清除。所有考虑能不能再客户端进行操作(当然有更好的方法websocked),当浏览器关闭时进行监听。
但是浏览器刷新的时候和关闭的时候,执行的方法基本相同
页面刷新 onbeforeunload – >onunload -->onload
页面关闭 onbeforeunload – >onunload
但是我们又没有办法监听onload是否执行,所有只能从前两个方法进行考虑
由于刷新的时候肯定会执行一系列的操作,所有执行时间肯定比关闭快,所以我们用这个思路进行判断

//经测试,可行
var beginTime = 0;
window.onbeforeunload = function (){
     beginTime = new Date().getTime();
 };
var executetime = 0;
window.onunload = function (){
        executetime = new Date().getTime() - beginTime ;
        if(differTime <= 5) {
            console.log("关闭")
             //异步请求,进行登录状态的修改
        }else{
            console.log("刷新")
        }

    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值