分享

如何通过session控制单点登录

 怀念真正的我 2010-08-26
           web服务器为每一个浏览器实例对应一个session。这个session有自己的一个独立id,这个id保存在浏览器的cookie中(这个cookie貌似随着这个浏览器实例的关闭而清除),访问web服务器的时候,web服务会根据你cookie中的sessionId来决定重新创建一个session还是使用已经存在的session。
如果使用桌面的ie图标打开一个IE窗口,这个窗口属于一个新的浏览器实例(其中不包含sessionid信息),这时候用这个IE访问web服务器的时候web服务器会为这个浏览器实例新创建一个httpsession,sessionId也是新的(sessionId保存到本地的cookie中),不会对你以前打开的窗口中的session产生覆盖,关闭ie窗口的时候cookie中的信息也就清除掉了。
如果是在打开的ie窗口中按“ctrl+n”打开一个ie窗口,这个窗口于刚才的窗口是同一个实例,与刚才的窗口共用session,所有的同一个ie实例的窗口都关掉后,会清除掉sessionId。

补充一点,可以通过人为的输入参数sessionId通知web服务器你使用的是哪个session(如果服务器存在这个session的话)。

*****************************************************************************************************************************************

         单点登录(有别于SSO:Single Sign On),首先解释一下对项目需求中的单点登录的理解:一个用户账号成功登录后,在该次session还未失效之前,不能在其他机器上登录同一个账号,这有点类似与QQ只能在同一台计算机上登录。好了,如何实现呢?现在分析一下:一次登录也就是一次会话(Session),那么我们可以很容易联想到通过控制session来实现单点登录,我的设想是这样的,登录后将用户信息保存到session中,如果此时在另外一台机器上一个相同的账号请求登录,通过遍历Web服务中所有session并判断其中是否包含同样的用户信息,通过这样的判断,在另一台机器上登录该账号是不成功的。
上面已经提到了,需要通过控制session,对web服务中所有session进行遍历操作,那么你肯定会想到application这个大对象了(当然你也可以采用缓存或者数据库),具体实现方法是这样的,首先在application中创建一个List<HttpSession>,用来保存每一次会话(session)对象,系统在验证用户登录请求时,通过遍历该list并加以判断,最后决定是否让该用户成功登录。OK,需求和设计都在上面了,接下来就是编码工作了哈。不过在这里还需要考虑几个问题:
1、如果登录后关闭了浏览器,想立即打开一个新的浏览器并登录将会失败,因为前一次登录后的session还没销毁,你需要等其销毁后方可再次登录成功,这种问题如何解决???哈哈,你是不是已经想到要用javascript处理一下下,即在关闭浏览器的时候触发一个事件,该事件就是通知来销毁当前session的。
2、第二个问题其实是接上一个问题而讨论的,用javascript触发浏览器关闭事件并不是一个好办法,因为有很多因素可能导致这个事件触发不成功,还有Firefox和IE这两个东东意见有时候并不统一,最后有一个比较可恶的问题就是,我在同一台机器上不能打开两个浏览器窗口去登录相同的账号,因为一个浏览器对应一个session啊!这就是为什么我在文章一开始要引用一些基本知识。
既然问题很严重,那就动脑壳去想办法啊!我在这里自言自语了半天,我不打算用中文继续讲下去了,直接code上场吧:
login.jsp
Html代码
  1. <form action="verifyLogin.do" method="post" name="form">  
  2. <table>  
  3. <tr align="center">  
  4. <td colspan="6" align="left"><fieldset STYLE='border:0;padding:14px;filter:glow(color=#0080ff,strength=3);letter-spacing:2px;'><font STYLE='font:12px/14px;color:#ffffff;font-weight:bold;'>请输入账号和密码:</font></fieldset>  
  5. </td>      
  6. </tr>  
  7. <tr>  
  8.     <td align="right">用户名:</td>  
  9.     <td><input type="text"  name="name" style="{ width: 100px;height: 15px;}" ></td>  
  10.     <td align="right">密  码:</td>  
  11.     <td><input type="password" name="pwd" style="{ width: 100px;height: 15px;}"></td>  
  12.        
  13.     <td>  
  14. <%--    <select name="authority" size="1">--%>  
  15. <%--      <option value="11">管理员</option>--%>  
  16. <%--      <option value="00">普通用户</option>--%>  
  17. <%--    </select>--%>  
  18.      <input type="hidden" name="authority" value="11" >  
  19.     </td>  
  20. </tr>  
  21. <tr align="center">  
  22. <td colspan="6" align="center">  
  23. <input name="" type="button" value="提    交" onMouseOver="this.style.backgroundColor='red';" onMouseOut="this.style.backgroundColor='';" class="button" onClick="check()">       
  24. <input name="" type="reset" value="重    置" onMouseOver="this.style.backgroundColor='red';" onMouseOut="this.style.backgroundColor='';" class="button">  
  25. </td>      
  26. </tr>  
  27. </table>  
  28. </form>  
 

VerifyLogin类处理请求:
Java代码
  1. String name=request.getParameter("name");   
  2.  String pwd=request.getParameter("pwd");   
  3.  String ip = request.getRemoteHost();   
  4.  //String Ip=request.getRemoteAddr();   
  5.   
  6.  User user=UserHelp.getUserByName(name);   
  7.  String err="";   
  8.  if(user!=null){   
  9.      if (user.getPwd().equals(pwd)){   
  10.           //out.println("验证成功!");   
  11.           boolean flag = true;   
  12.           List<HttpSession> sessions = (List<HttpSession>)application.getAttribute("sessionlist");   
  13.           for(int i = 0;i<sessions.size();i++){   
  14.             HttpSession ses = null;   
  15.             try{   
  16.                ses = sessions.get(i);   
  17.                User usr = (User)ses.getAttribute("user");   
  18.                String cuip = (String)ses.getAttribute("remoteHost");   
  19.                if(null!=usr&&usr.getName().equals(user.getName())&&!ip.equals(cuip)){//login repeatly!   
  20.                   flag = false;   
  21.                   err="<center><font color='red'>对不起该用户已经有人登录,您不能重复登录!</font></center><br><br>";   
  22.                   out.println(err);   
  23.                   break;   
  24.                }   
  25.             }catch(Exception e){   
  26.                sessions.remove(i);   
  27.             }   
  28.           }   
  29.           if(flag){   
  30.               session.setAttribute("user",user);   
  31.               session.setAttribute("remoteHost",ip);   
  32.               sessions.add(session);   
  33.               application.setAttribute("sessionlist",sessions);   
  34.           }   
  35.          if(flag&&user.getAuthority().equals("11")){   
  36.             response.sendRedirect("manageFrames2.htm");   
  37.           }   
  38.          if(flag&&user.getAuthority().equals("00")){   
  39.             response.sendRedirect("manageFrames1.htm");   
  40.           }   
  41.      }   
  42.      else{   
  43.          err="<center>密码错误,请重新登录!</center><br><br>";   
  44.           out.println(err);   
  45.      }   
  46.    }   
  47.  else{   
  48.    err="<center>无此用户,请重新登录!</center><br><br>";     
  49.      out.println(err);   
  50.  }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约