asp.net關於Cookie跨域的問題

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

跨次層網域

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

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.com127.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。看一下前台代碼,它沒有任何後台代碼

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Admin10000.Web.Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title></title></head><body>    <form id="form1" runat="server">    <div>              <script type="text/javascript">            var _frm = document.createElement("iframe");            _frm.style.display = "none";            _frm.src = "http://www.test2.com/SSO.ashx";            document.body.appendChild(_frm);          </script>       </div>    </form></body></html>

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

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Services;using System.Web.SessionState; namespace Admin10000.Web{    /// <summary>    /// $codebehindclassname$ 的摘要說明    /// </summary>    [WebService(Namespace = "http://tempuri.org/")]    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]    public class SSO : IHttpHandler    {         public void 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("");        }         public bool IsReusable        {            get            {                return false;            }        }    }}

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

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls; namespace Admin10000.Web{    public partial class GetCookie : System.Web.UI.Page    {        protected void Page_Load(object sender, 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調用形式:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Admin10000.Web.Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server">    <title></title></head><body>    <form id="form1" runat="server">    <div>        <script type="text/javascript" src="http://www.test2.com/SSO.ashx"></script>    </div>    </form></body></html>
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.