如何通過session控制單點登錄


如何通過session控制單點登錄

  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">
  5. <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>
  6. </fieldset>  
  7. </td>      
  8. </tr>  
  9. <tr>  
  10.     <td align="right">用戶名:</td>  
  11.     <td><input type="text"  name="name" style="{ width: 100px;height: 15px;}" ></td>  
  12.     <td align="right">密&nbsp;&nbsp;碼:</td>  
  13.     <td><input type="password" name="pwd" style="{ width: 100px;height: 15px;}"></td>  
  14.        
  15.     <td>  
  16. <%--    <select name="authority" size="1">--%>  
  17. <%--      <option value="11">管理員</option>--%>  
  18. <%--      <option value="00">普通用戶</option>--%>  
  19. <%--    </select>--%>  
  20.      <input type="hidden" name="authority" value="11" >  
  21.     </td>  
  22. </tr>  
  23. <tr align="center">  
  24. <td colspan="6" align="center">  
  25. <input name="" type="button" value="提&nbsp;&nbsp;&nbsp;&nbsp;交" 
  26. onMouseOver="this.style.backgroundColor='red';" 
  27. onMouseOut="this.style.backgroundColor='';" class="button" 
  28. onClick="check()">&nbsp;&nbsp;&nbsp;&nbsp;   
  29. <input name="" type="reset" value="重&nbsp;&nbsp;&nbsp;&nbsp;置"
  30.  onMouseOver="this.style.backgroundColor='red';" 
  31. onMouseOut="this.style.backgroundColor='';" class="button">  
  32. </td>      
  33. </tr>  
  34. </table>  
  35. </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.  }  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM