轉(zhuǎn)自:http://www.zhangsichu.com/blogview.asp?Content_Id=89
問(wèn)題描述:在一個(gè)比較復(fù)雜的網(wǎng)站環(huán)境下。有多個(gè)產(chǎn)品向外提供服務(wù)。每個(gè)
產(chǎn)品下都有自己的用戶登錄界面。現(xiàn)在需要設(shè)計(jì)一個(gè)統(tǒng)一的登錄界面。當(dāng)用戶在這個(gè)界面登錄后就可以自由的使用各個(gè)產(chǎn)品和服務(wù)。同時(shí)意味著用戶用一個(gè)賬號(hào)可以
在不同服務(wù)里登錄,另一方面就是在一個(gè)服務(wù)里面登錄后可以無(wú)障礙的漫游到其他服務(wù)里面去。
實(shí)際應(yīng)用:Sohu的Passport將
focus.cn,17173.com,sogou.com,chinaren.com這四個(gè)域名下的產(chǎn)品全部整合在一起了。用戶在這四個(gè)站點(diǎn)中任何一個(gè)
地方都可以登錄。當(dāng)用戶登錄后可以自由的使用其他域名下的服務(wù)?,F(xiàn)在很多網(wǎng)站上都有bbs blog
album服務(wù)。這些服務(wù)一般也是自己維護(hù)自己的用戶信息。當(dāng)發(fā)展到一定時(shí)候,也需要一個(gè)Passport機(jī)制整合所有服務(wù),使用戶可以單點(diǎn)登錄。
Sohu的實(shí)現(xiàn)方案
在http://passport.sohu.com/ 登錄后 fiddler可以攔截到如下的返回信息:
由
于passport.sohu.com的登錄界面使用了iframe隱藏提交。所以頁(yè)面沒(méi)有看到刷新。隱藏的iframe把用戶名和加密的
password和其他信息發(fā)送給了passport.sohu.com。passport.sohu.com在Response中設(shè)置了成功登錄的
cookie。這個(gè)cookie可以證實(shí)這個(gè)用戶成功登錄了passport.sohu.com。
當(dāng)用戶在Passport成功登錄后??蛻舳说腏avascript根據(jù)成功登錄的標(biāo)志,操作iframe請(qǐng)求http://passport.sohu.com/sso/crossdomain_all.jsp?action=login 因?yàn)樵谕粋€(gè)域名下,沒(méi)有跨域,在這次請(qǐng)求中,上次成功登陸的cookie會(huì)被一并帶著回去。服務(wù)器端檢查到成功登錄的cookie后會(huì)Render回一段同時(shí)登錄多個(gè)站點(diǎn)的html。
這
段html
要向4個(gè)地址發(fā)送請(qǐng)求。截至到現(xiàn)在都是在相同的Domain(passport.sohu.com)請(qǐng)求和返回,為真正的跨站點(diǎn)登錄做準(zhǔn)備,真正的跨站點(diǎn)
登錄還沒(méi)有開(kāi)始。下面passport.sohu.com通過(guò)sso/crossdomain.jsp 在服務(wù)器端進(jìn)行Redirect 設(shè)置http
head
為302進(jìn)行跳轉(zhuǎn)。跳轉(zhuǎn)后在這個(gè)跳轉(zhuǎn)后的域名下設(shè)置登錄成功的cookie。這就是sohu實(shí)現(xiàn)跨站點(diǎn)登錄的核心過(guò)程。下面是
passport.sohu.com登錄17173.com的過(guò)程。
1. 通過(guò)http://passport.sohu.com/sso/crossdomain_all.jsp?action=login Render回來(lái)的script <script type="text/javascript" src=" 請(qǐng)求同域下的http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com 這時(shí)passport.sohu.com下成功登錄的cookie會(huì)被帶回去。
2. 服務(wù)器看到成功登錄的Cookie后。在服務(wù)器端計(jì)算出一個(gè)加密后的17173.com的登錄Url,并Redirect到這個(gè)Url。
3. 17173.com
從url的QueryString中取得信息。并在Response中設(shè)置Cookie。這個(gè)Cookie終于寫(xiě)到了17173.com下。而不是
passport.sohu.com下。從而使得用戶在17173.com下登錄。其實(shí)用戶在17173.com下手動(dòng)登錄也是寫(xiě)上同樣的Cookie。
以后用戶再訪問(wèn)17173.com的頁(yè)面時(shí)這個(gè)Cookie會(huì)被帶回去。這就表示用戶在17173.com下成功登錄過(guò)了。
經(jīng)過(guò)上面的步驟。用戶在passport.sohu.com下登錄的同時(shí)也在其他站點(diǎn)登錄了。
在上面的過(guò)程中,最核心的技巧就是在指定的域下寫(xiě)入想要的Cookie:
1. Sohu
使用了在同一個(gè)域名登錄后通過(guò)再次請(qǐng)求這個(gè)域名下某個(gè)鏈接后,得到要登錄站點(diǎn)的請(qǐng)求Url,通過(guò)javascript使隱藏的iframe請(qǐng)求要登錄站點(diǎn)
的Url,服務(wù)器端接到請(qǐng)求Redirect到要登錄站點(diǎn),然后通過(guò)Response寫(xiě)入Cookie,完成跨域名寫(xiě)Cookie的操作。這種寫(xiě)
Cookie的方式,需要在跳轉(zhuǎn)時(shí)對(duì)請(qǐng)求的QueryString進(jìn)行加密。接受方需要對(duì)QueryString進(jìn)行解密。
2.
這種做法在服務(wù)器端不需要特別的處理。只要寫(xiě)好相應(yīng)Post操作 WriteCookie操作 Redirect操作
就可以了。在FireFox下就可以正常工作了。但是在IE下寫(xiě)Cookie的操作還不行,總是寫(xiě)不進(jìn)去Cookie。需要在Response中加入一段
特別的Header. P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM
STA PRE COM NAV OTC NOI DSP COR"
這個(gè)Http Header 是P3P安全的要求。P3P的詳解 http://www.oreilly.com.cn/book.php?bn=7-302-07170-5
微軟對(duì)這個(gè)的解釋:http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q323752
一個(gè)更加輕量級(jí)的方案
Sohu
的通行證方案已經(jīng)可以輕松的將各個(gè)域名下的用戶都同步登錄了。但是在實(shí)現(xiàn)上Sohu會(huì)讓客戶端的瀏覽器請(qǐng)求兩次passport.sohu.com。在第
二次得到一個(gè)登錄多個(gè)站點(diǎn)的地址列表。在第三次請(qǐng)求時(shí)通過(guò)本域下的cookie進(jìn)行身份驗(yàn)證,最后在服務(wù)器端跳轉(zhuǎn)到一個(gè)含有加密Key的其它域名的Url
地址,最終寫(xiě)入登錄成功的Cookie。除去最開(kāi)始的登錄,要求用戶在登錄后再進(jìn)行兩次請(qǐng)求。并且服務(wù)器端要再做一次跳轉(zhuǎn)。Sohu的做法可能由于
Sohu服務(wù)器環(huán)境和數(shù)據(jù)存儲(chǔ)的結(jié)構(gòu)所決定。
其實(shí)總共只需一次登錄請(qǐng)求,和每個(gè)域名下一次請(qǐng)求就可以完成多站點(diǎn)登錄了,同時(shí)也不需要服務(wù)器端的跳轉(zhuǎn)。
跨站點(diǎn)的請(qǐng)求由script的src發(fā)出。各個(gè)域名下的ssologin處理QueryString中的key,解密key,驗(yàn)證Key的合法性。在Response中寫(xiě)入登錄成功的Cookie。完成跨站點(diǎn)Cookie的寫(xiě)入。
兩種方案的比較
1. Sohu使用的登錄方式,請(qǐng)求次數(shù)多,但是每次請(qǐng)求都有對(duì)應(yīng)的驗(yàn)證過(guò)程,在服務(wù)端跳轉(zhuǎn)時(shí),重要的跳轉(zhuǎn)Url地址在HttpHeader中,使得跳轉(zhuǎn)地址更加安全,使得用戶在跨域登錄時(shí)非常安全可靠。
2.
輕量級(jí)方案的登錄方式,請(qǐng)求次數(shù)少,沒(méi)有服務(wù)器端的跳轉(zhuǎn),對(duì)服務(wù)器壓力小。但是需要對(duì)Key進(jìn)行加密解密。跳轉(zhuǎn)的Url會(huì)在Response的Http
Body中Render給用戶。在使用輕量級(jí)方案的時(shí)候,最好在Key中加上時(shí)間戳,過(guò)期時(shí)間設(shè)置為3分鐘。Key過(guò)期認(rèn)為這個(gè)Key是非法Key,不在
Response中寫(xiě)入登錄成功的Cookie。
聯(lián)系客服