首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET Cookie 跨域解決方案:二級域名共享與頂級域名跨域實戰(含 P3P 標頭應對 IE)

     編輯:ASP.NET 基礎

跨域 Cookie 核心原理

Cookie 的 Domain 屬性控制作用域:

  • Domain=test1.com → 所有 *.test1.com 可訪問(二級域名共享)
  • 跨頂級域名(test1.com ↔ test2.com)瀏覽器安全策略禁止直接共享

場景一:二級域名共享(標準做法)


// www.test1.com 設置 Cookie
HttpCookie cookie = new HttpCookie("SSO_Token", "user123");
cookie.Domain = "test1.com";      // 關鍵:設置根域名
cookie.Path = "/";
cookie.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(cookie);

// bbs.test1.com、api.test1.com 直接讀取 Request.Cookies["SSO_Token"]

條件: 同一根域名,DNS 解析到同一組伺服器或共享機器密鑰(machineKey)。

場景二:頂級域名跨域(test1.com → test2.com)

核心思路: 利用 iframe 或 script src 跨域請求目標域,在目標域內設置 Cookie(同源策略允許頁面向自身域設置 Cookie)。

實戰演示:三頁面協作

1. Default.aspx (test1.com) - 發起跨域請求


<%@ Page Language="C#" %>
<html><body>
<script>
    // 方式 A: 隱藏 iframe
    var frm = document.createElement("iframe");
    frm.style.display = "none";
    frm.src = "https://www.test2.com/SSO.ashx?token=abc123";
    document.body.appendChild(frm);
    
    // 方式 B: script src (需 SSO.ashx 返回 JS)
    // var s = document.createElement("script");
    // s.src = "https://www.test2.com/SSO.ashx?token=abc123";
    // document.body.appendChild(s);
</script>
</body></html>

2. SSO.ashx (test2.com) - 接收參數並設置 Cookie


public class SSO : IHttpHandler {
    public void ProcessRequest(HttpContext context) {
        string token = context.Request["token"];
        
        HttpCookie cookie = new HttpCookie("SSO_Token", token);
        cookie.Domain = "test2.com";  // 設置自身域
        cookie.Path = "/";
        cookie.Expires = DateTime.Now.AddYears(1);
        context.Response.Cookies.Add(cookie);
        
        // 關鍵:P3P 標頭解決 IE iframe 禁用第三方 Cookie
        context.Response.AddHeader("P3P", "CP=\"CAO PSA OUR\"");
        
        context.Response.ContentType = "text/plain";
        context.Response.Write("OK"); // 或返回 JS: parent.callback('OK');
    }
    public bool IsReusable => false;
}

3. GetCookie.aspx (test2.com) - 驗證 Cookie 讀取


protected void Page_Load(object sender, EventArgs e) {
    if (Request.Cookies["SSO_Token"] != null)
        Response.Write($"Token: {Request.Cookies["SSO_Token"].Value}");
    else
        Response.Write("Cookie 未找到");
}

本地測試環境搭建

  1. 修改 C:\Windows\System32\drivers\etc\hosts:
    127.0.0.1  www.test1.com
    127.0.0.1  www.test2.com
  2. IIS 綁定兩個網站,Host Header 分別設置,指向同一物理路徑或不同應用
  3. 訪問 https://www.test1.com/Default.aspx → 自動調用 test2.com 設置 Cookie → 訪問 https://www.test2.com/GetCookie.aspx 驗證

P3P 標頭深度解析

IE 6+ 默認阻止第三方 Cookie(iframe 跨域)。P3P (Platform for Privacy Preferences) 聲明隱私政策,滿足 IE 要求方可設置 Cookie。


// 最小可用策略
context.Response.AddHeader("P3P", "CP=\"CAO PSA OUR\"");
// 完整範例
// CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
  • Firefox/Chrome/Safari/Edge 現代瀏覽器不再依賴 P3P,但 IE/舊版 Edge 仍需
  • P3P 已被 W3C 廢棄,長期方案應遷移至 OAuth/OIDC/共享 Session 存儲

替代方案對比

方案原理優點缺點適用場景
iframe + P3P跨域請求目標域設置 Cookie實現簡單、兼容舊瀏覽器P3P 廢棄、被廣告攔截器阻塞、安全風險舊系統維護、IE 必須支援
JSONP 回調<script src="...?callback=fn"> 返回 JS 設置 Cookie無 iframe、可攜帶數據同源腳本注入風險、僅 GET簡單數據同步
共享資料庫/RedisSessionID 寫入共享存儲,各域讀取安全、可控、支援複雜會話需基礎設施、延遲略高企業級 SSO、微服務架構
OAuth 2.0 / OIDC授權碼流程獲取 Token,各域驗證行業標準、安全、解耦實現複雜、需授權服務器新系統、開放平台、跨組織
LocalStorage + postMessage主域寫 LocalStorage,子域 postMessage 讀取現代瀏覽器支援、無 Cookie 限制需同源父頁面、無 HTTP 自動攜帶前端重、無後台依賴場景

避坑指南

  • Domain 設置規則: 不能設置為 .com、.cn 等公共後綴;必須包含至少一個點(test.com)
  • Secure + SameSite: 跨域 HTTPS 環境必須 Secure=true; SameSite=None (NET Core 3.1+/Framework 4.7.2+)
  • 機器密鑰同步: 多伺服器場景 <machineKey validationKey="..." decryptionKey="..." /> 保持一致
  • Cookie 名稱衝突: 不同應用用前綴區分(App1_Token、App2_Token)

結語

「跨域 Cookie 是歷史妥協產物,現代架構應採用 Token 化認證(JWT/OAuth)+ 共享會話存儲。」—— 理解 iframe+P3P 原理有助於維護舊系統,新專案請直接走標準授權流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved