cookie 跨域訪問的解決方案

Cookie 同域單點登陸 

最近在作一個單點登陸的系統整合項目,以前咱們使用控件實現單點登陸(之後能夠介紹一下)。但如今爲了知足客戶需求,在不使用控件狀況下實現單點登陸,先來介紹一下單點登陸。 
 
單點登陸:多個不一樣系統整合到統一加載個平臺,用戶在任何一個系統登陸後,能夠訪問這個統一加載上的全部系統。登陸以後,用戶的權限和信息再也不受某個系統的限制,即便某個系統出現故障(包括統一加載平臺),其餘系統仍是能正常使用的。這就須要用戶權限等信息保存到客戶端,不受服務器的限制。 

在cookie相關文檔信息中,提到cookie是不能跨域訪問的,可是在二級域名是能夠共享cookie的。這樣就是咱們的項目有了侷限性,必須將多個系統的域名統一,做爲二級域名,統一平臺提供使用主域名。這樣就能夠實現cookie的單點登陸了。  

在這裏介紹一下cookie:  

1.cookie是一個存儲在客戶端的字符串屬性,能夠用它對當前網頁的cookie進行讀,寫,增.刪等操做;javascript可以用document對象的cookie屬性對cookie進行操做; 

2.cookie的四個可選屬性: 

  2.1 cookie的生存期屬性:expires;默認狀況下,cookie只在瀏覽器會話期存在.退出瀏覽器就丟失;能夠用expires設置時間;退出瀏覽器後就不會丟失並存爲客戶端瀏覽器的cookie文件;過了時間後cookie失效,還會自動刪除cookie文件. 

  2.2 path屬性:默認狀況下,在同一個目錄下文件能夠調用;  
 
    例如:http://hanj.com/c1/1.html設置的cookie能夠被http://hanj.com/c1/2.html調用.但不能被http://hanj.com/c2/目錄下的文件調用;  

    但如把path屬性設成"/";則在http://hanj.com/下的全部文件均可調用此cookie. 

  2.3 domain屬性:例如設成".hanj.com"則在.hanj.com下的全部服務器下的文件均可以調用cookie. 
 
  2.4 安全屬性:默認狀況下爲false;用http協議不安全傳輸;true:用https等協議安全傳輸. 

3.cookie的侷限性: 

瀏覽器最多保存300個cookie;爲單個web服務器的最多隻能保存20個cookie;每一個cookie不能超過4000個字節.  

單點登陸實現環境:
 
統一平臺域名:www.hanj.com 

子系統1:a.hanj.com 
 
子系統2:b.hanj.com 

子系統3:c.hanj.com 

統一加載平臺和各子系統都是不一樣的服務器,統一加載平臺提供登陸認證服務,在統一加載平臺認證系統上登陸後,用戶均可以被其餘的系統識別。 
 
/**
函數名稱:getCookie
函數功能:獲取指定名稱的cookie的值
輸入參數:須要測試的字符串
返回參數:
*/

function getSSOCookie()  
{  
    var arrStr = document.cookie.split("; ");  
    for(var i = 0;i < arrStr.length;i ++){  
        var temp = arrStr[i].split("=");  
        if(temp[0] == "sso") {  
          return unescape(temp[1]);  
        }  
    }  
    return "";  
}  


/**
函數名稱:addCookie
函數功能:添加cookie
輸入參數:須要測試的字符串
返回參數:
*/

function addSSOCookie(objValue)  
{ 
    var str = "sso" + "=" + escape(objValue);  
    if(true){//爲0時不設定過時時間,瀏覽器關閉時cookie自動消失  
        str += "; path=/";  
    }  
    document.cookie = str;  
}  
  
 
/**
函數名稱:delCookie
函數功能:刪除cookie
輸入參數:須要測試的字符串
返回參數:
*/

function delCookie() {
  //爲了刪除指定名稱的cookie,能夠將其過時時間設定爲一個過去的時間 var date = new Date(); date.setTime(date.getTime() - 10000); document.cookie = "sso" + "=a; expires=" + date.toGMTString()+"; path=/"; }
 
用戶在統一加載平臺認證系統認證經過後,使用addSSOCookie,用戶權限信息保存到了cookie中,其餘平臺經過調用getSSOCookie,取得用戶信息。這樣用戶就能夠再也不受平臺限制,而實現自由訪問各個系統了。  

在addSSOCookie方法中,沒有設置cookie的失效時間,這樣在瀏覽器關閉後,cookie就自動消失。注意:這樣cookie的有效性只能在同一瀏覽器進程,若是從新打開了一個瀏覽器進程,cookie信息是獲取不到的,也就是單點登陸只能在同一個瀏覽器進程有效。若是想在不用瀏覽器進程中共享cookie信息,那就設置失效時間,以下:  

function addCookie(objValue,objHours){//添加cookie  
  var str = "sso"+ "=" + escape(objValue);  
  if(objHours > 0){//爲0時不設定過時時間,瀏覽器關閉時cookie自動消失  
  var date = new Date();  
  var ms = objHours*3600*1000;  
  date.setTime(date.getTime() + ms);  
  str += "; expires=" + date.toGMTString()+"; path=/; domain=.hanj.com";  
  }  
  document.cookie = str;  
}  
 
這樣cookie在指定的時間後失效。但這樣安全性不能保證,若是時間設置過短,用戶在使用中,可能cookie就失效了,須要從新登陸。若是時間過長,用戶在下次訪問,或電腦重起訪問,cookie還在有效期中,有可能別其餘人使用。cookie不能準確的刪除,存在安全隱患。   
Cookie跨域單點登陸  

爲了快速、簡單的實現這一功能,首先想到就是經過JS操做Cookie並讓兩個不一樣域的cookie可以相互訪問,這樣就可達到了上述的效果,具體實現過程大體可分如下兩個步驟:  

1、在A系統下成功登陸後,利用JS動態建立一個隱藏的iframe,經過iframe的src屬性將A域下的cookie值做爲 get參數重定向到B系統下b.aspx頁面上; 

var _frm = document.createElement("iframe");  
_frm.style.display="none";   
_frm.src="http://b.com/b.jsp?test_cookie=xxxxx";   
document.body.appendChild(_frm);   

二、在B系統的b.aspx頁面中來獲取A系統中所傳過來的cookie值,並將所獲取到值寫入cookie中,這樣就簡單的實現了cookie跨域的訪問; 不過這其中有個問題須要注意,就是在IE瀏覽器下這樣操做不能成功,須要在b.aspx頁面中設置P3P HTTP Header就能夠解決了(具體詳細信息能夠參考:http://www.w3.org/P3P/),P3P設置代碼爲:
/*
*也能夠在html加入標記
<meta http-equiv="P3P" content='CP="IDC DSP COR CURa ADMa  OUR IND PHY ONL COM STA"'>
*/
Response.AppendHeader("P3P", "CP='IDC DSP COR CURa ADMa  OUR IND PHY ONL COM STA'");  
相關文章
相關標籤/搜索