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個字節.
單點登錄實現環境:
但如把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的值
輸入參數:需要測試的字符串
返回參數:
*/
函數名稱:getCookie
函數功能:獲取指定名稱的cookie的值
輸入參數:需要測試的字符串
返回參數:
*/
1
2
3
4
5
6
7
8
9
10
11
|
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
輸入參數:需要測試的字符串
返回參數:
*/
1
2
3
4
5
6
7
8
9
|
function
addSSOCookie(objValue) { var str
= "sso" + "=" +
escape(objValue); if ( true ){ //爲0時不設定過期時間,瀏覽器關閉時cookie自動消失 str
+= ";
path=/" ; } document.cookie
= str; } |
/**
函數名稱:delCookie
函數功能:刪除cookie
輸入參數:需要測試的字符串
返回參數:
*/
用戶在統一加載平臺認證系統認證通過後,使用addSSOCookie,用戶權限信息保存到了cookie中,其他平臺通過調用getSSOCookie,取得用戶信息。這樣用戶就可以不再受平臺限制,而實現自由訪問各個系統了。
在addSSOCookie方法中,沒有設置cookie的失效時間,這樣在瀏覽器關閉後,cookie就自動消失。注意:這樣cookie的有效性只能在同一瀏覽器進程,如果重新打開了一個瀏覽器進程,cookie信息是獲取不到的,也就是單點登錄只能在同一個瀏覽器進程有效。如果想在不用瀏覽器進程中共享cookie信息,那就設置失效時間,如下:
函數名稱:delCookie
函數功能:刪除cookie
輸入參數:需要測試的字符串
返回參數:
*/
1
2
3
4
5
6
|
<br>function
delCookie() {<br> //爲了刪除指定名稱的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信息,那就設置失效時間,如下:
1
2
3
4
5
6
7
8
9
10
|
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頁面上;
2、在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"'>
*/
Cookie跨域單點登錄
爲了快速、簡單的實現這一功能,首先想到就是通過JS操作Cookie並讓兩個不同域的cookie能夠相互訪問,這樣就可達到了上述的效果,具體實現過程大致可分以下兩個步驟:
1、在A系統下成功登錄後,利用JS動態創建一個隱藏的iframe,通過iframe的src屬性將A域下的cookie值作爲 get參數重定向到B系統下b.aspx頁面上;
1
2
3
4
|
var _frm
= document.createElement( "iframe" ); _frm.style.display= "none" ; _frm.src= "http://b.com/b.jsp?test_cookie=xxxxx" ; document.body.appendChild(_frm); |
2、在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"'>
*/
1
|
Response.AppendHeader( "P3P" , "CP='IDC
DSP COR CURa ADMa OUR IND PHY ONL COM STA'" ); |