1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 同一账号同一时间在不同地点登陆实现登陆剔出功能

同一账号同一时间在不同地点登陆实现登陆剔出功能

时间:2024-05-27 07:33:29

相关推荐

同一账号同一时间在不同地点登陆实现登陆剔出功能

公司项目中最近涉及到在网站登陆账号时,同一账号同一时间在不同地点登陆时要实现踢出功能,通俗的讲也就是用户的账号若已经登陆,那么此时此用户再在别的地方登陆就要将先前登陆的账号踢下线。

先理一下思路,我们知道在客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。session在用户第一次访问服务器的时候自动创建,也就是说每个用户对应一个session。那么我们只要使先前登陆的用户失效就能实现踢出功能。

方案实现,在登陆逻辑处添加一个方法,在方法中我们实现相应的同一账号登陆账号具备踢出下线功能。首先设定一个Map1,在里面我们以键值对的方式存储当前在线用户的用户ID和其对应的session,同时设定Map2,同样以键值对的方式存储被踢出用户的用户ID和其对应的session,另外为了防止java的垃圾回收机制将我们设定的Map回收,还要将两个Map存储到全局缓存application中。每当有用户登陆时会先判断是否有以此用户ID为Key的Map存在,若存在则说明用户已登陆,就将已登陆用户的用户ID和其对应的session存放到Map2中,并将已登陆用户对应的session注销,此时已登陆用户就会因session失效而掉线;若不存在则说明此用户没有在别处登陆。无论用户有没有在别处登陆,都将当前登陆的用户ID和其对应的session存入Map1中。这样就会实现用户登陆剔出功能。但这样还没有结束,我们将已登陆的用户剔出后,还要以弹框的形式提示他“当前用户已在别处登陆,请返回登陆页重新登陆”。弹框功能的实现是通过前台ajax监测后台登陆状态的形式实现的,ajax每隔一段时间向后台发送固定参数,以用户ID为唯一标识,检测登陆状态,若发现用户session已被放到踢出队列(即相应的Map中),则进行提示。另外,由于在JS中的函数是放在单独文件中实现的,所以无法实时获取对应的用户ID,在这里采用的是以cookie的形式将用户信息在登陆的html页面中存入,并在JS中获取并传入ajax的参数中。最后将正常登陆用户和被踢出的用户ID、登陆时间、登陆IP、登陆(或踢出状态)、sessionid都存入数据库中,以备出现问题可以进行查询。

--------------------------------------------------------------------------------------------下面上代码---------------------------------------------------------------------

校验用户是否登陆代码:

public void isLoaded(String sUser,HttpSession sessions,PageData pd) throws Exception{LoginDao dao=new LoginDao(pd);ServletContext application=pd.getSession().getServletContext();SimpleDateFormat mDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String cTime=mDate.format(new Date());String IpAdrr=dao.getClientIp(pd);HashMap<String, HttpSession> cMap=(HashMap<String, HttpSession>) application.getAttribute(sUser);try {//判断是否当前用户名已登录if(!(cMap==null)){HttpSession mSession=cMap.get(sUser);String mIP=fUserMap.get(sUser);String mSessionId=mSession.getId();//被踢掉sessionString cSessionId=sessions.getId();//在线session//判断是否为同一浏览器登陆if(!(mSessionId.equals(cSessionId))){passMap.put(sUser+"T", mSession);application.setAttribute(sUser+"T", passMap);dao.addLoginInfo(sUser, cTime, mIP, mSessionId, "用户在别处登陆");if(!(mSession.getAttribute("ifNull")==null)){mSession.invalidate();} }}} catch (Exception e) {log.debug("session已失效");}finally{//无论当前用户名登陆与否,都将当前用户名与其对应session存储到map中sessions.setAttribute("ifNull", "a");hUserMap.put(sUser, sessions);fUserMap.put(sUser, IpAdrr);application.setAttribute(sUser,hUserMap);log.debug("登录的用户名:"+sUser);log.debug("登录的时间:"+cTime);log.debug("登录的IP地址:"+IpAdrr);log.debug("当前sessionId:"+sessions.getId()); //将登陆信息存入数据库dao.addLoginInfo(sUser, cTime, IpAdrr, sessions.getId(), "正常登陆");}}

校验用户是否已被剔出代码,并形成弹框提示状态:

public boolean tUserState(String tUser,PageData pd){String CurrentSessionId=pd.getSession().getId(); ServletContext application=pd.getSession().getServletContext();//被踢掉的存储mapHashMap<String, HttpSession> pMap=(HashMap<String, HttpSession>) application.getAttribute(tUser+"T");//在线mapHashMap<String, HttpSession> zMap=(HashMap<String, HttpSession>) application.getAttribute(tUser);if(!(pMap==null)){//只有被踢掉的sessionid与请求的sessionid相同时才有提示框,也就是说只有被踢掉的浏览器才提示if(!(zMap.get(tUser).getId()).equals(CurrentSessionId)){//检测到有同一用户被踢后,就将该用户信息在application中删除,防止其他用户登录检测到不为空application.removeAttribute(tUser+"T");return true; } else{return false;}}else{return false;}}

接收ajax参数,并向ajax返回用户状态代码:

public void loginState(IRequestCycle cycle) throws Exception{PageData pd = getPageData();IData data =pd.getData();IData mloginState=new DataMap();LoginBean bean = (LoginBean)BeanFactory.getBeanFactory().getBean(LoginBean.class);SimpleDateFormat mDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String cTime=mDate.format(new Date()); boolean mState=bean.tUserState(data.getString("tUser"),pd);log.debug("Myajax:"+data.getString("tUser"));String nState=String.valueOf(mState);mloginState.put("STATE", nState);log.debug("loginStateRun:"+nState+",time:"+cTime);pd.setAjaxData(mloginState);}

html登陆页面cookie获取参数代码:

function setCookie() { var Days = 60; //cookie 将被保存两个月 var exp = new Date(); //获得当前时间 exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000); //换成毫秒 document.cookie = "kang"+ "=" + escape($("#STAFF_LOGINID").val()) + ";expires=" + exp.toGMTString(); }

js文件ajax登陆状态监测代码:

$(function () {setInterval("loginAjax()", 20000);});function getCookie(name) { //取出cookie var strCookie = document.cookie; //cookie的保存格式是 分号加空格 "; " var arrCookie = strCookie.split("; "); for ( var i = 0; i < arrCookie.length; i++) { var arr = arrCookie[i].split("="); if (arr[0] == name) { return arr[1]; } } return ""; } function loginAjax(){var t=getCookie("kang");var params = {page:"Home", listener:"loginState",param:'&tUser='+t, partId:null, formId:"loginForm", afterFn:afterState};$.ajaxSubmit(params);}function afterState(data){var state=data[0].STATE;if(state=="true"){layer.alert('您的账号已在别处登陆,请返回登录页重新登陆!', 8, '温馨提示');}}

写在最后,实现此功能还有其他方法,比如说用监听器监听等。本方法中尚存在不足,由于ajax的监听是每隔一段时间监测,所以提示弹框的实时性可能不是太高,若时间设置太短可能会对服务器造成较大的压力,但功能还是能实现。若有更好方案的同志请留言给我,我们可以一起讨论一下。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。