處理session跨伺服器、跨域失效問題
最近遇到一個需求,就是在單體架構的系統上要將系統中的檔案資源分離到另一個資源系統中,這時候就需要考慮到跨域的問題了。網上解決方式有以下幾種:
網上跨域的解決方案
Java中解決跨域的方式主要有兩種:
1)第一種解決方法 後臺程式碼在被請求的Servlet中新增Header設定response.setHeader("Access-Control-Allow-Origin", "*");
2)通過jsonp跨域請求的方式(具體什麼是jsonp跨域百度上可以搜尋到很多資料,這裡就不過多解釋)
但是java處理的跨域問題只是解決了前端可以正常呼叫跨域訪問不同後臺的介面的問題,但是
1、基於NFS的Session共享
2、基於資料庫的Session共享
3、基於Cookie的Session共享
4、基於Memcache或redis的Session共享
我需要的只是在跨域的時候session不失效就ok了,但是這幾種解決方式感覺代價太大,不太適合我們目前的小系統開發要求。於是我就想到先去了解cookie和session的執行流程
Cookie、session的互動原理
Cookie是儲存在客戶端,session是儲存在伺服器端的,具體的詳細介紹百度有很多,這裡就不用介紹了。首先我們需要處理
1、cookie.setDomain("www.baidu.com"); // 設定域名
2、cookie.setPath("/search"); // 設定路徑
一般我們需要把path設定為“/”代表根路徑。Domain設定為同一一個一級域名,如:aaa.hshkj.com/bbb.hshkj.com,我們就可以設定 COOKIE 的域為 .hshkj.com,這樣兩個子域名就可以訪問此COOKIE。這樣各個伺服器共享同一客戶端 SESSION ID 的目的就達到了。一下是cookie
理解的cookie與session的互動流程,我們就明白了session失效的原因,比如客戶端訪問A伺服器的時候,生成的jsessionid的之為11111,但是當瀏覽器去呼叫B伺服器的資源時,會攜帶這個jsessionid過去,發現B伺服器上沒有與之對應的session,這時B伺服器又會生成一個新的session,並通過set-cookie方法把與該新的session對應的jsessionid(如222)設定到cookie中,這時候瀏覽器的jsessionid就變為了222,當瀏覽器再訪問A伺服器時,發現與222對應的沒有session,這時候A伺服器又會重新生成新的session
解決cookie、session跨域問題,如何解決session因跨域而失效的問題
知道了問題的所在,那我們可以提出解決的方案了(方法一是我提出的解決方案,方法二是網上提供的方案):
1、保證jsessionid在兩個server的上都一致,這樣就不會重新生成session了
2、因為我用的是tomcat,所以我們可以讓自己的tomcat使用各自的jsessionid
第一種的解決方案的樣例程式碼
在資源伺服器中新增一個filter類,在doFilter方法中執行
String jsessionId = CookieUtils.getCookieValue(httpRequest, "JSESSIONID");
//將session獲取出來
HttpSession session = httpRequest.getSession();
//System.out.println("-----jsessionId------->>"+jsessionId);
CookieUtils.setCookie(httpRequest, response, "JSESSIONID", jsessionId);
第二種方法,tomcat的\conf\context.xml,修改session的別名
<Context sessionCookieName="SHGJSESSIONID" sessionCooliePath="/">
這樣在該tomcat下獲取jsessionid別名就是SHGJSESSIONID對應的值
注意:方法一的時候要先獲取session,然後再通過cookie修改JSESSIONID的值,這樣才能保證JSESSIONID的值沒有變。因為如果獲取session 的放在我們定義的cookie後面的話,系統在自動生成session時,呼叫setcookie方法就會在我們的setcookie的後面,這樣就達不到我們想要設計的效果了。
總結:其實很多時候,我們要解決問題時,我們都是需要先了解原理,然後再大膽的猜測解決方案,大膽的去嘗試,你就會收到意想不到的效果