Cookie/Session的跨域共享

單點(diǎn)登錄(SSO——Single Sign On)對(duì)于我們來(lái)說(shuō)已經(jīng)不陌生了。對(duì)于大型系統(tǒng)來(lái)說(shuō)使用單點(diǎn)登錄可以減少用戶(hù)很多的麻煩。就拿百度來(lái)說(shuō)吧,百度下面有很多的子系統(tǒng)——百度經(jīng)驗(yàn)、百度知道、百度文庫(kù)等等,如果我們使用這些系統(tǒng)的時(shí)候,每一個(gè)系統(tǒng)都需要我們輸入用戶(hù)名和密碼登錄一次的話(huà),我相信用戶(hù)體驗(yàn)肯定會(huì)直線(xiàn)下降。當(dāng)然,對(duì)于個(gè)人博客這類(lèi)系統(tǒng)來(lái)說(shuō)根本就用不上單點(diǎn)登錄了。
假如,我們的系統(tǒng)很龐大,但是就是這一個(gè)系統(tǒng),并沒(méi)有什么子系統(tǒng)。這時(shí)我們也不需要單點(diǎn)登錄。這里不涉及多臺(tái)主機(jī)負(fù)載均衡session共享的問(wèn)題。

在同一個(gè)域名下的不同站點(diǎn)是如何進(jìn)行驗(yàn)證的
如果兩個(gè)站點(diǎn)可以共享相同的驗(yàn)證Cookie,這將很容易實(shí)現(xiàn)使用同一個(gè)用戶(hù)登錄多個(gè)站點(diǎn)。按照HTTP協(xié)議規(guī)定,兩個(gè)站點(diǎn)是可以共享Cookie的。前提是這兩個(gè)站點(diǎn)是在同一個(gè)域名下面(或者是二級(jí)域名也可)。這種情況是屬于同域下的Cookie。瀏覽器會(huì)將Cookie以及該Cookie所屬的域存在本地。當(dāng)你對(duì)該域下的任何子站點(diǎn)進(jìn)行訪(fǎng)問(wèn)的時(shí)候,瀏覽器都會(huì)將這些Cookie發(fā)送給站點(diǎn)系統(tǒng)。
假設(shè)我們有兩個(gè)站點(diǎn)

www.onmpw.com/site1
www.onmpw.com/site2

這兩個(gè)站點(diǎn)共享同一個(gè)主機(jī)地址,并且二者在同一域名下。加入你剛剛登錄了www.onmpw.com/site1,你的瀏覽器會(huì)有一個(gè)來(lái)自www.onmpw.com/site1的身份鑒證的cookie。當(dāng)你點(diǎn)擊site1下的任何的子頁(yè)面的時(shí)候,這些cookie都會(huì)發(fā)送給site1。這是很容易理解的。同樣的,當(dāng)你請(qǐng)求www.onmpw.com/site2的時(shí)候,對(duì)于site2下面的任何頁(yè)面這些cookie也同樣會(huì)隨著請(qǐng)求發(fā)送過(guò)去。為什么是這樣,因?yàn)樵跒g覽器端存儲(chǔ)的cookie的域是www.onmpw.com。site1和site2兩個(gè)站點(diǎn)是同屬于該域的。所以對(duì)于該域下的cookie,兩個(gè)站點(diǎn)都可以得到。只需要按照正常的驗(yàn)證方式進(jìn)行驗(yàn)證即可。因?yàn)槎叩膕essionId是相同的,只要它們的session信息是保存在同一個(gè)地方即可。

同一個(gè)域但是不同的子域如何進(jìn)行單點(diǎn)登錄
假如我們的站點(diǎn)是按照下面的域名進(jìn)行部署的

sub1.onmpw.com
sub2.onmpw.com

這兩個(gè)站點(diǎn)共享同一域onmpw.com。默認(rèn)情況下,瀏覽器會(huì)發(fā)送cookie所屬的域?qū)?yīng)的主機(jī)。也就是說(shuō),來(lái)自于sub1.onmpw.com的cookie默認(rèn)所屬的域是.sub1.onmpw.com。因此,sub2.onmpw.com不會(huì)得到任何的屬于sub1.onmpw.com的cookie信息。因?yàn)樗鼈兪窃诓煌闹鳈C(jī)上面,并且二者的子域也是不同的。
這時(shí)可以設(shè)置二者的cookie信息在同一個(gè)域下。
1.登錄sub1.onmpw.com系統(tǒng)
2.登錄成功以后,設(shè)置cookie信息。這里需要注意,我們可以將用戶(hù)名和密碼存到cookie中,但是在設(shè)置的時(shí)候必須將這cookie的所屬域設(shè)置為頂級(jí)域 .onmpw.com。這里可以使用setcookie函數(shù),該函數(shù)的第四個(gè)參數(shù)是用來(lái)設(shè)置cookie所述域的。

cookie.setDomain(".onmpw.com");

3.訪(fǎng)問(wèn)sub2.onmpw.com系統(tǒng),瀏覽器會(huì)將cookie中的信息username和password附帶在請(qǐng)求中一塊兒發(fā)送到sub2.onmpw.com系統(tǒng)。這時(shí)該系統(tǒng)會(huì)先檢查session是否登錄,如果沒(méi)有登錄則驗(yàn)證cookie中的username和password從而實(shí)現(xiàn)自動(dòng)登錄。
4.sub2.onmpw.com 登錄成功以后再寫(xiě)session信息。以后的驗(yàn)證就用自己的session信息驗(yàn)證就可以了。
當(dāng)然,先登錄sub2.onmpw.com的方式也是相同的。經(jīng)過(guò)上面的步驟就可以實(shí)現(xiàn)不同二級(jí)域名的單點(diǎn)登錄了。

但是,這里存在一個(gè)問(wèn)題就是sub1系統(tǒng)退出以后,除了可以清除自身的session信息和所屬域?yàn)?onmpw.com的cookie的信息。它并不能清除sub2系統(tǒng)的session信息。那sub2仍然是登錄狀態(tài)。也就是說(shuō),這種方式雖說(shuō)可以實(shí)現(xiàn)單點(diǎn)登錄,但是不能實(shí)現(xiàn)同時(shí)退出。原因是,我們只是把用戶(hù)名和密碼的cookie通過(guò)setDomain設(shè)置成共享cookie。但是二者的sessionId是不同的,而且這個(gè)sessionId在瀏覽器中也是以cookie的形式存儲(chǔ)的,不過(guò)它所屬的域并不是.onmpw.com。也就是說(shuō)二者的sessionId是不同的。

解決方案:
把第一次登錄生成的JSESSIONID,通過(guò)setDomain放到一個(gè)共享的的自定義的cookie中。之后訪(fǎng)問(wèn)二級(jí)域名的時(shí)候,將自定義cookie中的的值取出來(lái),然后在放到JSESSIONID的cookie的值中。參考

Cookie c = new Cookie("JSESSIONID", session.getId());  
c.setDomain("abc.com");  
resp.addCookie(c);

要點(diǎn):不同的子域的Cookie可以共享。Session跨子域需要把JESSIONID寫(xiě)進(jìn)共享Cookie(雖然JSEESIONID就是本身Cookie,但由于tomcat創(chuàng)建的,他的domain屬性是跟你當(dāng)前站的域名是嚴(yán)格保持一致的)。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容