如何通過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代碼
<form action="verifyLogin.do" method="post" name="form">  
<table>  
<tr align="center">  
<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>  
</td>      
</tr>  
<tr>  
    <td align="right">用戶名:</td>  
    <td><input type="text"  name="name" style="{ width: 100px;height: 15px;}" ></td>  
    <td align="right">&nbsp;&nbsp;碼:</td>  
    <td><input type="password" name="pwd" style="{ width: 100px;height: 15px;}"></td>         
    <td>  
<%--    <select name="authority" size="1">--%>  
<%--      <option value="11">管理員</option>--%>  
<%--      <option value="00">普通用戶</option>--%>  
<%--    </select>--%>  
     <input type="hidden" name="authority" value="11" >  
    </td>  
</tr>  
<tr align="center">  
<td colspan="6" align="center">  
<input name="" type="button" value="提&nbsp;&nbsp;&nbsp;&nbsp;交" onMouseOver="this.style.backgroundColor='red';" onMouseOut="this.style.backgroundColor='';" class="button" onClick="check()">&nbsp;&nbsp;&nbsp;&nbsp;   
<input name="" type="reset" value="重&nbsp;&nbsp;&nbsp;&nbsp;置" onMouseOver="this.style.backgroundColor='red';" onMouseOut="this.style.backgroundColor='';" class="button">  
</td>      
</tr>  
</table>  
</form>  
VerifyLogin類處理請求:
Java代碼
String name=request.getParameter("name");   
 String pwd=request.getParameter("pwd");   
 String ip = request.getRemoteHost();   
 //String Ip=request.getRemoteAddr();   
  
 User user=UserHelp.getUserByName(name);   
 String err="";   
 if(user!=null){   
     if (user.getPwd().equals(pwd)){   
          //out.println("驗證成功!");   
          boolean flag = true;   
          List<HttpSession> sessions = (List<HttpSession>)application.getAttribute("sessionlist");   
          for(int i = 0;i<sessions.size();i++){   
            HttpSession ses = null;   
            try{   
               ses = sessions.get(i);   
               User usr = (User)ses.getAttribute("user");   
               String cuip = (String)ses.getAttribute("remoteHost");   
               if(null!=usr&&usr.getName().equals(user.getName())&&!ip.equals(cuip)){//login repeatly!   
                  flag = false;   
                  err="<center><font color='red'>對不起該用戶已經有人登錄,您不能重復登錄!</font></center><br><br>";   
                  out.println(err);   
                  break;   
               }   
            }catch(Exception e){   
               sessions.remove(i);   
            }   
          }   
          if(flag){   
              session.setAttribute("user",user);   
              session.setAttribute("remoteHost",ip);   
              sessions.add(session);   
              application.setAttribute("sessionlist",sessions);   
          }   
         if(flag&&user.getAuthority().equals("11")){   
            response.sendRedirect("manageFrames2.htm");   
          }   
         if(flag&&user.getAuthority().equals("00")){   
            response.sendRedirect("manageFrames1.htm");   
          }   
     }   
     else{   
         err="<center>密碼錯誤,請重新登錄!</center><br><br>";   
          out.println(err);   
     }   
   }   
 else{   
   err="<center>無此用戶,請重新登錄!</center><br><br>";     
     out.println(err);   
 }  

 


免責聲明!

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



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