1. 程式人生 > >java 操作 Cookie 跨域(同頂級域名)

java 操作 Cookie 跨域(同頂級域名)

需求:2個二級欄目需要用同一個是否扥登陸的Cookie

實現:
登陸方法驗證通過後:

  1. Cookie loginCookie = new Cookie("ccUserId",userMap.get("user_id").toString());  
  2.                 loginCookie.setDomain("xxx.com");  
  3.                 loginCookie.setPath("/");  
  4.                 response.addCookie(loginCookie);  

退出登陸程式碼:
  1. Cookie[] cookies = request.getCookies();  
  2. for(Cookie c :cookies ){  
  3.     c = new Cookie(c.getName(), null);  
  4.     c.setDomain("xxx.com");  
  5.     c.setPath("/");  
  6.     c.setMaxAge(0);  
  7.     response.addCookie(c);  
  8. }  

xxx.com 2處要一致,才能刪除COOKIE。

我參考的資料:

Cookie是一個偉大的發明,它允許Web開發者保留他們的使用者的登入狀態。但是當你的站點有一個以上的域名時就會出現問題了。在Cookie規範上說,一個cookie只能用於一個域名,不能夠發給其它的域名。因此,如果在瀏覽器中對一個域名設定了一個cookie,這個cookie對於其它的域名將無效。如果你想讓你的使用者從你的站點中的其中一個進行登入,同時也可以在其它域名上進行登入,這可真是一個大難題。

跨二級域名

  我們知道cookie是可以跨二級域名來訪問,這個很好理解,例如你 www.test1.com 在的web應用程式建立了一個cookie,要想在bbs.test1.com這樣的二級域名對應的應用程式中訪問,就必須你在建立cookie的時候設定domain引數domain=test1.com。 以asp.NET為例 程式碼如下:

1 2 3 4 HttpCookie cookie =new HttpCookie("name","www.Admin10000.com"); cookie.Domain = "test1.com"; cookie.Path = "/"; Response.Cookies.Add(cookie);

跨頂級域名

  如果我不是二級域名而是完全在不同頂級域名中,例如 www.test1.com 所在的web應用程式建立了一個cookie,想要在 www.test2.com 或其二級域名的應用程式中訪問,改怎麼辦呢?我們知道靠常規反的方法是訪問不了的,關鍵我們就是看看有沒有方法可以訪問。事實是Cookie可以在一定條件下跨域,而不是隨心所欲的實現跨域。

  我們來做個測試,看看兩個站點 www.test1.com 和 www.test2.com 如何實現cookie跨域訪問。 按照常規我們需要有2個頂級域名,並且有DNS伺服器才能夠配置域名,否則我們是無法驗證的,但是這裡我們也沒有必要那麼麻煩,我們可以通過修改hosts檔案來模擬。在 c:\windows\system32\drivers\etc 中有 hosts檔案,在末尾新增上

127.0.0.1    www.test1.com
127.0.0.1    www.test2.com 

兩行,就可以將本機用上面的域名訪問本機迴環地址了。我們只需要在IIS上部署一套程式,ip為本機迴環地址,用兩個域名分別訪問就可以了。

  我們新建三個頁面,分別是 Default.aspx、SSO.ashx、GetCookie.aspx。

  其中Default.aspx是 www.test1.com 的頁面,訪問的地址是 http://www.test1.com/Default.aspx。看一下前臺程式碼,它沒有任何後臺程式碼

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Admin10000.Web.Default" %> <headrunat="server"> <title></title> </head> <body> <formid="form1"runat="server"> <div> <scripttype="text/javascript"> var _frm = document.createElement("iframe"); _frm.style.display = "none"; document.body.appendChild(_frm);   </script> </div> </form> </body> </html>

  另外一個是 SSO.ashx 頁面,我們認為它是 www.test2.com 的頁面,前臺沒有任何程式碼,後臺程式碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Web.SessionState; namespaceAdmin10000.Web { /// <summary> /// $codebehindclassname$ 的摘要說明 /// </summary> [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] publicclass SSO : IHttpHandler { publicvoid ProcessRequest(HttpContext context) { HttpCookie cookie =new HttpCookie("name","www.Admin10000.com"); cookie.Domain ="test2.com"; cookie.Path ="/"; cookie.Expires = DateTime.Now.AddMinutes(10000); context.Response.Cookies.Add(cookie); context.Response.ContentType ="text/plain"; context.Response.AddHeader("P3P","CP=CAO PSA OUR"); context.Response.Write(""); } publicbool IsReusable { get { returnfalse; } } } }

  最後是 GetCookie.aspx 頁面,它同樣是www.test2.com下的頁面,沒有前臺程式碼,只有後臺程式碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespaceAdmin10000.Web { publicpartial classGetCookie : System.Web.UI.Page { protectedvoid Page_Load(objectsender, EventArgs e) { if(Request.Cookies["name"] !=null) { Response.Write(Request.Cookies["name"].Value); } } } }

  好了,現在我們訪問測試,通過訪問 http://www.test1.com/Default.aspx 之後,這時會通過iframe載入呼叫SSO.ashx這個頁面,執行後臺程式碼建立cookie,然後訪問 http://www.test2.com/GetCookie.aspx  我們得到了相應的cookie。說明在www.test1.com下建立的cookie在www.test2.com下是可以訪問到的。

要注意的地方:

  admin10000.com提示 SSO.ashx 的後臺程式碼中有一句:context.Response.AddHeader("P3P", "CP=CAO PSA OUR"); 是用來設定P3P響應頭。是因為IE瀏覽器支援的P3P導致iframe跨站點時cookie被阻止,無法建立cookie。(FireFox目前還不支援P3P安全特性,FireFox自然也不存在此問題。不需要新增P3P響應頭。)

  通過iframe的src屬性將test1.com域下的cookie值作為get引數重定向到test2.com域下SSO.ashx頁面上,SSO.ashx獲取test1.com域中所傳過來的cookie值,並將所獲取到值寫入cookie中,這樣就簡單的實現了cookie跨域的訪問。

  另外Default.aspx頁面也可改為JS呼叫形式:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Admin10000.Web.Default" %> <headrunat="server"> <title></title> </head> <body> <formid="form1"runat="server"> <div> <scripttype="text/javascript"src=></script> </div> </form> </body> </html>