實現跨域cookie共享(轉載)

問題描述:在一個比較複雜的網站環境下。有多個產品向外提供服務。每一個產品下都有本身的用戶登陸界面。如今須要設計一個統一的登陸界面。 當用戶在這個界面登陸後就能夠自由的使用各個產品和服務。同時意味着用戶用一個賬號能夠在不一樣服務裏登陸,另外一方面就是在一個服務裏面登陸後能夠無障礙的 漫遊到其餘服務裏面去。

實際應用:Sohu的Passport將focus.cn,17173.com,sogou.com,chinaren.com這四個域 名下的產品所有整合在一塊兒了。用戶在這四個站點中任何一個地方均可以登陸。當用戶登陸後能夠自由的使用其餘域名下的服務。如今不少網站上都有bbs blog album服務。這些服務通常也是本身維護本身的用戶信息。當發展到必定時候,也須要一個Passport機制整合全部服務,使用戶能夠單點登陸。

Sohu的實現方案在http://passport.sohu.com/ 登陸後 fiddler能夠攔截到以下的返回信息:

因爲passport.sohu.com的登陸界面使用了iframe隱藏提交。因此頁面沒有看到刷新。隱藏的iframe把用戶名和加 密的password和其餘信息發送給了passport.sohu.com。passport.sohu.com在Response中設置了成功登陸的 cookie。這個cookie能夠證明這個用戶成功登陸了passport.sohu.com。

當用戶在Passport成功登陸後。客戶端的Javascript根據成功登陸的標誌,操做iframe請求 http://passport.sohu.com/sso/crossdomain_all.jsp?action=login 由於在同一個域名下,沒有跨域,在此次請求中,上次成功登錄的cookie會被一併帶着回去。服務器端檢查到成功登陸的cookie後會Render回一 段同時登陸多個站點的html。

這段html 要向4個地址發送請求。截至到如今都是在相同的Domain(passport.sohu.com)請求和返回,爲真正的跨站點登陸作準備,真正的跨站點 登陸尚未開始。下面passport.sohu.com經過sso/crossdomain.jsp 在服務器端進行Redirect 設置http head 爲302進行跳轉。跳轉後在這個跳轉後的域名下設置登陸成功的cookie。這就是sohu實現跨站點登陸的核心過程。下面是 passport.sohu.com登陸17173.com的過程。

1. 經過http://passport.sohu.com/sso/crossdomain_all.jsp?action=login Render回來的script <script type="text/javascript" src="http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com"></script> 請求同域下的http://passport.sohu.com/sso/crossdomain.jsp?action=login& domain=17173.com 這時passport.sohu.com下成功登陸的cookie會被帶回去。

2. 服務器看到成功登陸的Cookie後。在服務器端計算出一個加密後的17173.com的登陸Url,並Redirect到這個Url。

3. 17173.com從url的QueryString中取得信息。並在Response中設置Cookie。這個Cookie終於寫到了 17173.com下。而不是passport.sohu.com下。從而使得用戶在17173.com下登陸。其實用戶在17173.com下手動登陸 也是寫上一樣的Cookie。之後用戶再訪問17173.com的頁面時這個Cookie會被帶回去。這就表示用戶在17173.com下成功登陸過了。

通過上面的步驟。用戶在passport.sohu.com下登陸的同時也在其餘站點登陸了。

在上面的過程當中,最核心的技巧就是在指定的域下寫入想要的Cookie:

1. Sohu使用了在同一個域名登陸後經過再次請求這個域名下某個連接後,獲得要登陸站點的請求Url,經過javascript使隱藏的iframe請求要 登陸站點的Url,服務器端接到請求Redirect到要登陸站點,而後經過Response寫入Cookie,完成跨域名寫Cookie的操做。這種寫 Cookie的方式,須要在跳轉時對請求的QueryString進行加密。接受方須要對QueryString進行解密。

2. 這種作法在服務器端不須要特別的處理。只要寫好相應Post操做 WriteCookie操做 Redirect操做就能夠了。在FireFox下就能夠正常工做了。可是在IE下寫Cookie的操做還不行,老是寫不進去Cookie。須要在Response中加入一段特別的Header. P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"

這個Http Header 是P3P安全的要求。P3P的詳解 http://www.oreilly.com.cn/book.php?bn=7-302-07170-5 微軟對這個的解釋:http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q323752

一個更加輕量級的方案

Sohu的通行證方案已經能夠輕鬆的將各個域名下的用戶都同步登陸了。可是在實現上Sohu會讓客戶端的瀏覽器請求兩次 passport.sohu.com。在第二次獲得一個登陸多個站點的地址列表。在第三次請求時經過本域下的cookie進行身份驗證,最後在服務器端跳 轉到一個含有加密Key的其它域名的Url地址,最終寫入登陸成功的Cookie。除去最開始的登陸,要求用戶在登陸後再進行兩次請求。而且服務器端要再 作一次跳轉。Sohu的作法可能因爲Sohu服務器環境和數據存儲的結構所決定。

其實總共只需一次登陸請求,和每一個域名下一次請求就能夠完成多站點登陸了,同時也不須要服務器端的跳轉。

跨站點的請求由script的src發出。各個域名下的ssologin處理QueryString中的key,解密key,驗證Key的合法性。在Response中寫入登陸成功的Cookie。完成跨站點Cookie的寫入。

兩種方案的比較

1. Sohu使用的登陸方式,請求次數多,可是每次請求都有對應的驗證過程,在服務端跳轉時,重要的跳轉Url地址在HttpHeader中,使得跳轉地址更加安全,使得用戶在跨域登陸時很是安全可靠。

2. 輕量級方案的登陸方式,請求次數少,沒有服務器端的跳轉,對服務器壓力小。可是須要對Key進行加密解密。跳轉的Url會在Response的Http Body中Render給用戶。在使用輕量級方案的時候,最好在Key中加上時間戳,過時時間設置爲3分鐘。Key過時認爲這個Key是非法Key,不在 Response中寫入登陸成功的Cookie。 javascript

本文來源於:http://www.yaosansi.com/post/1218.html php

相關文章
相關標籤/搜索