備注學(xué)院

          LuLu

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            5 隨筆 :: 50 文章 :: 16 評(píng)論 :: 0 Trackbacks

          問(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ù)。現(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可以攔截到如下的返回信息:

          Click to Open in New Window

          由于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。

          Click to Open in New Window

          當(dāng)用戶在Passport成功登錄后。客戶端的Javascript根據(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。

          Click to Open in New Window

          這段html 要向4個(gè)地址發(fā)送請(qǐng)求。截至到現(xiàn)在都是在相同的Domain(passport.sohu.com)請(qǐng)求和返回,為真正的跨站點(diǎn)登錄做準(zhǔn)備,真正的跨站點(diǎn)登錄還沒(mé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=" ' target=_blank tip href_cetemp='http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com"> '>http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com"></script> 請(qǐng)求同域下的http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com 這時(shí)passport.sohu.com下成功登錄的cookie會(huì)被帶回去。

          Click to Open in New Window

          2.  服務(wù)器看到成功登錄的Cookie后。在服務(wù)器端計(jì)算出一個(gè)加密后的17173.com的登錄Url,并Redirect到這個(gè)Url。

          Click to Open in New Window

          3.  17173.com從url的QueryString中取得信息。并在Response中設(shè)置Cookie。這個(gè)Cookie終于寫到了17173.com下。而不是passport.sohu.com下。從而使得用戶在17173.com下登錄。其實(shí)用戶在17173.com下手動(dòng)登錄也是寫上同樣的Cookie。以后用戶再訪問(wèn)17173.com的頁(yè)面時(shí)這個(gè)Cookie會(huì)被帶回去。這就表示用戶在17173.com下成功登錄過(guò)了。

          Click to Open in New Window

          經(jīng)過(guò)上面的步驟。用戶在passport.sohu.com下登錄的同時(shí)也在其他站點(diǎn)登錄了。

          在上面的過(guò)程中,最核心的技巧就是在指定的域下寫入想要的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寫入Cookie,完成跨域名寫Cookie的操作。這種寫Cookie的方式,需要在跳轉(zhuǎn)時(shí)對(duì)請(qǐng)求的QueryString進(jìn)行加密。接受方需要對(duì)QueryString進(jìn)行解密。

          2.  這種做法在服務(wù)器端不需要特別的處理。只要寫好相應(yīng)Post操作 WriteCookie操作 Redirect操作 就可以了。在FireFox下就可以正常工作了。但是在IE下寫Cookie的操作還不行,總是寫不進(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地址,最終寫入登錄成功的Cookie。除去最開始的登錄,要求用戶在登錄后再進(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)。

          Click to Open in New Window

          跨站點(diǎn)的請(qǐng)求由script的src發(fā)出。各個(gè)域名下的ssologin處理QueryString中的key,解密key,驗(yàn)證Key的合法性。在Response中寫入登錄成功的Cookie。完成跨站點(diǎn)Cookie的寫入。

          兩種方案的比較

          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中寫入登錄成功的Cookie。

          posted on 2009-10-13 23:47 smildlzj 閱讀(200) 評(píng)論(0)  編輯  收藏 所屬分類: Web開發(fā)
          主站蜘蛛池模板: 安塞县| 科技| 资源县| 临洮县| 云霄县| 布尔津县| 芜湖市| 凤冈县| 巴南区| 武平县| 周口市| 芜湖县| 马公市| 新化县| 滦平县| 隆安县| 湘西| 常州市| 凯里市| 大名县| 嘉祥县| 永年县| 呼玛县| 南丹县| 深泽县| 宜昌市| 重庆市| 张家川| 黄浦区| 封开县| 师宗县| 巴楚县| 军事| 正定县| 大宁县| 石林| 三原县| 大竹县| 神农架林区| 韩城市| 永川市|