用户登录唯一性验证(检查用户登录状态 是否同一浏览器地址登录)

核心是通过 缓存、Cookie以及SpringMVC拦截器 实现

登陆时以用户id为key在缓存中保存时间戳 在cookie中以一个全局变量为key保存时间戳
	 String times = new Date().getTime() + "";
      memCache.put(userId + "mem_time_key", times);      WebUtils.setCookie(response,"flag", times, 30);

我们知道cookie是保存在浏览器本地的,缓存保存在服务端

此时 还是这个用户 在另一个终端登录,会重复 上面代码的操作,更新在服务端的缓存 key相同 ,而value时间戳发生了变化


下一步,需要在每个页面引入功能写入功能js文件即可,写一个实现每次载入页面都会定时器10s执行的查询后台的 flag 对应的缓存的vlaue 并与本地cookie中的时间戳相比较,如果不一致说明,用户在别的浏览器登陆过,则可以清空cookie 强制退出,由于 后一次登录更改服务器缓存的时间戳,所以前一次登录会被强制退出。

function callbackFun() {
    if (isLogin()) {
        $.ajax({
            url: "/check/userIsLogin.json",
            data: {},
            type: "post",
            dataType: "json",
            async: false,
            success: function (result) {
                if (result.success == false) {
                    if (result.message == "OthersIsLogin") {
                        dialog("下线提示", "您的账号在其他地方登录,若非本人操作,请重新登录。", 6, '/index');
                        DeleteCookie("flag"); //删除本地时间戳
                    }
                } else {
                    setTimeout(callbackFun, 10000); //延时递归调用自己,间隔调用时间,单位毫秒
                }
            }
        });
    }
}

后台Jvav代码 比较时间戳

             String  times =  (String)memCache.get(userId+"mem_time_key");
            if (ObjectUtils.isNotNull(userId) && ObjectUtils.isNotNull(times)) {
                String cookieTime = WebUtils.getCookie(request, "flag");
                if (StringUtils.isNotEmpty(times) && StringUtils.isNotEmpty(cookieTime) && !times.equals(cookieTime)) {
                    
                    memCache.remove(MemConstans.USEREXPAND_INFO + userId); //清除用户信息(不包含时间戳)
                    WebUtils.deleteCookie(request, response, CommonConstants.USER_SINGEL_ID);//清除用户cookie信息
                    json = this.getJsonMap(false, "OthersIsLogin", null);
                }
            }

如果实现随时可修改的是否检测登录唯一性呢?

其实更灵活的办法是把上述判断代码写入springmvc的拦截器的前置增强中

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.preHandle(request, response, handler);

        JsonObject userJsonObject = SingletonLoginUtils.getLoginUser(request); 
        if(ObjectUtils.isNotNull(userJsonObject)){ //是否有登录用户判断 防止空指针
            if(ischeck){ //可从数据库查询 是否检测唯一性标识
                 //登录状态的验证,是否被其他人踢掉
                        //上述Java判断代码功能一致即可
                    } 
                }else{//未登录时跳转到登录页面
            if(request.getRequestURL().indexOf("/mobile")>-1){
                response.sendRedirect("/mobile/login");
            }else{
                response.sendRedirect("/login");
            }
                    }
}


你可能感兴趣的:(Java,Web)