發(fā)表時間:2008-11-07 最后修改:2008-11-07 在實際使用中,由于域名不同,但又需要跨域訪問。主要應(yīng)用場景是,客戶在英國的購物網(wǎng)站-http://www..uk(簡稱:uk站) 中往購物車中放置了商品,最后,轉(zhuǎn)至https://l來進(jìn)行支付工作。這時就碰到了跨域訪問時,Session丟失的問題。 先說一下,我們用的服務(wù)器是Tomcat。Tomcat是通過url中的jsessionid以及cookie中的jsessionid來取得會話ID的。Tomcat先會查詢URL后面有沒有跟jsessionid。然后,再去解析Cookie中的jsessionid。如果cookie中有的話,那么,不管之前從URL中有沒有找會jsessionid,都會使用cookie中找到的。詳情參見Tomcat中的CoyoteAdapter類。 問題1:我打開瀏覽器,在uk站中買了一件商品,當(dāng)我點(diǎn)擊頁面中的Check Out鏈接時,頁面跳入了https://checkout.的支付頁面后,用戶購物車?yán)锏纳唐吩谔D(zhuǎn)在支付頁面中消失了。 問題原因:由于兩者的域名不同,在跳轉(zhuǎn)到支付頁面時,丟失了原來的會話信息。無論是URL還是cookie中都找不到會話ID了。Tomcat創(chuàng)建了一個空空如也的新會話。 解決辦法:重寫鏈接,在支付鏈接后加上jsessionid,也就是像這樣https://checkout.;jsessionid=A8AB5D19484BFCF26E8E4F708E2F6C91.jvm1。在轉(zhuǎn)到支付頁面時,由于此時瀏覽器中https://checkout.域名的cookie中沒有任何信息,則Tomcat會使用URL中取得的sessionId。這樣,就能繼續(xù)使用uk站中的會話了。 問題2:通過URL重寫,我們可以在https://checkout.的頁面能夠看到購物網(wǎng)站的信息了,我本以為一切到此結(jié)束了,沒想到,又出現(xiàn)了新的問題。在支付過程中,頁面使用Ajax和服務(wù)器做些數(shù)據(jù)的交互??擅看谓粨Q,服務(wù)器居然都報session中找不到用戶登錄信息的exception。仔細(xì)看了下日志,服務(wù)器在處理支付頁面上的初次的Ajax請求時,居然創(chuàng)建了一個新的Session。 問題原因:在通過Ajax發(fā)送請求時,Tomcat無法從URL中取得會話ID,之后,便試著去Cookie中查詢信息??纱藭r,https://checkout.下的cookie竟然是空空如也的。之前從購物網(wǎng)站跳轉(zhuǎn)至https://checkout.時,Tomcat從URL中取得了原會話ID。此時,Tomcat是繼續(xù)使用原有session,而沒有創(chuàng)建新的session,便沒有向瀏覽器的cookie寫入信息JSESSIONID的信息了(這是我猜測的,沒看代碼證實過)。 解決辦法:既然能在轉(zhuǎn)入支付頁面時使用原有的Session,那么,就在剛轉(zhuǎn)入支付頁面時,把sessionid寫入cookie不就行了嗎?這里我暫時用js把sessionid寫入了cookie中。之后做了幾次測試都順利地通過了。 問題3:好了,當(dāng)我以為一切都OK的時候,又出現(xiàn)了一個問題。我先打開www.,也就是checkout.的主域名。接著再打開www..uk進(jìn)行購買的操作。此時,當(dāng)我轉(zhuǎn)入https://checkout.時,session又丟失了。 問題原因:其實,這里的session沒有丟失。通過SessionID來看,在轉(zhuǎn)入https://checkout.時,由于之前打開了其主域名www.,在cookie中留下了host為xxx的session的信息。而在從購物網(wǎng)站轉(zhuǎn)入支付頁面時,Tomcat先從URL中取得了uk站的會話ID,但是最后又從cookie中取到了www.的會話ID,并且使用了它。 解決辦法:暫無。 候選辦法1:修改Tomcat中的CoyoteAdapter類,讓它以URL中的jsessionid為主,以cookie中的為輔。但是,這樣做就會有個很大的問題。那就是,如果用戶收藏了一個購物站中的一商品的鏈接。而這個鏈接后面又跟了一個已經(jīng)失效的jsessionid,那么,服務(wù)器端會由于拿不到這個失效的jsessionid對應(yīng)的Session,而去創(chuàng)建一個新的會話。這樣子,就很有可能在同一個瀏覽器中訪問相同的站點(diǎn),但卻面對著不同的會話。 候選辦法2:讓公司再單獨(dú)開個域名,專門負(fù)責(zé)處理check out。在進(jìn)入這個域名前,對header中的referer信息進(jìn)行驗證,如果來自購物網(wǎng)站,則對請求進(jìn)行正常處理。反之,則重定向到其它的域名。不知道重寫向時,會不會向cookie中寫入信息?這個不知道可行否。 不知道各位對應(yīng)問題3的情況有什么處理建議嗎?還望大家不吝賜一二呀。 PS. 據(jù)說,SSL證書是針對域名收錢的。所以,我們針對不同國家或有不同的域名。但對于支付,都是跳轉(zhuǎn)到https://checkout.這一個來進(jìn)行的。這樣,只需要一張SSL證書就行了。 補(bǔ)充:目前我們都只是在做一個國家的站點(diǎn),checkout測試也是針對一個國家的。但實際上,各個不同的國家的站點(diǎn),其實是不同的webapp。它們在支付時都會轉(zhuǎn)向的那個checkout網(wǎng)站,也只能是個獨(dú)立的webapp了。那么,這就不是單靠個sessionid就能和各個國家的站點(diǎn)共享他們的session的問題了。 而是兩個不同的應(yīng)用間,共享數(shù)據(jù)的問題了。 兜了圈子,猛然發(fā)現(xiàn),現(xiàn)在我在努力解決的問題,不是將來要實際面對的問題。狂汗。 ![]() |
|