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

ASP.NET Core / ASP.NET Cookie 完整操作指南:建立、讀取、選項、安全性、SameSite、GDPR 合規

     編輯:關於C語言

前言

Cookie 是 HTTP 無狀態協定中維持狀態的核心機制。現代 ASP.NET Core 提供強型別 IResponseCookies/IRequestCookies 介面與 CookieOptions 完整控制屬性;舊版 ASP.NET 使用 HttpCookie 與 HttpResponse.Cookies。本文系統整理兩種框架的 Cookie 操作、安全屬性設定、SameSite 政策、GDPR 合規與常見陷阱。

核心 API 對照

功能ASP.NET CoreASP.NET (Framework)
寫入 CookieResponse.Cookies.Append(key, value, options)Response.Cookies.Add(new HttpCookie(key, value))
讀取 CookieRequest.Cookies[key] 或 TryGetValueRequest.Cookies[key]?.Value
刪除 CookieResponse.Cookies.Delete(key, options)Response.Cookies.Add(new HttpCookie(key) { Expires = DateTime.Now.AddDays(-1) })
選項類別CookieOptionsHttpCookie 屬性

ASP.NET Core 完整範例

1. 基本寫入與讀取

// Controller / Minimal API / Razor Pages
public IActionResult Login(string username)
{
    // 簡單寫入 (Session Cookie,瀏覽器關閉即失效)
    Response.Cookies.Append("username", username);
    return Content("已寫入 Cookie");
}

public IActionResult Read()
{
    if (Request.Cookies.TryGetValue("username", out string value))
        return Content($"歡迎回來, {value}");
    return Content("找不到 Cookie");
}

2. 完整 CookieOptions 設定 (生產環境標準)

var options = new CookieOptions
{
    // 必要安全屬性
    HttpOnly = true,                    // 禁止 JavaScript 讀取 (防 XSS 竊取)
    Secure = true,                      // 僅 HTTPS 傳輸 (生產環境必開)
    SameSite = SameSiteMode.Strict,     // 防 CSRF:Strict/Lax/None
    
    // 生命週期
    Expires = DateTimeOffset.UtcNow.AddDays(30), // 持久化 Cookie
    // MaxAge = TimeSpan.FromDays(30),            // 替代 Expires (相對時間)
    
    // 作用域
    Path = "/",                         // 整站可用
    Domain = ".example.com",            // 子域名共享 (可選)
    
    // 進階
    IsEssential = true                  // GDPR:標記為必要 Cookie,同意條幅不阻擋
};

Response.Cookies.Append("auth_token", jwtToken, options);

3. 刪除 Cookie (必須匹配原建立選項)

// 必須指定相同 Path、Domain、Secure、SameSite
Response.Cookies.Delete("auth_token", new CookieOptions
{
    Path = "/",
    Domain = ".example.com",
    Secure = true,
    SameSite = SameSiteMode.Strict
});

4. 子域名共享 Cookie (單一登入 SSO 基礎)

// 主域名 example.com 設定
options.Domain = ".example.com"; // 開頭加點,包含所有子域名
// 或精確指定
options.Domain = "app.example.com"; // 僅此子域名

// 子域名 api.example.com 讀取時自動攜帶

ASP.NET (Framework) 完整範例

// 建立帶子鍵的 Cookie (舊版特有功能)
var cookie = new HttpCookie("user_prefs")
{
    HttpOnly = true,
    Secure = true, // 需 IIS 設定 RequireSSL
    Expires = DateTime.Now.AddDays(30),
    Domain = ".example.com",
    Path = "/"
};
cookie.Values["theme"] = "dark";
cookie.Values["lang"] = "zh-TW";
cookie.Values["timezone"] = "Asia/Taipei";
Response.Cookies.Add(cookie);

// 讀取子鍵
if (Request.Cookies["user_prefs"] != null)
{
    string theme = Request.Cookies["user_prefs"]["theme"];
    string lang = Request.Cookies["user_prefs"]["lang"];
}

// 刪除
var delCookie = new HttpCookie("user_prefs") { Expires = DateTime.Now.AddDays(-1) };
Response.Cookies.Add(delCookie);

安全屬性深度解析

HttpOnly

  • 功能:瀏覽器禁止 JavaScript (document.cookie) 存取。
  • 防護:緩解 XSS 攻擊竊取 Session ID / JWT。
  • 建議:所有認證/授權 Cookie 必須設為 true。

Secure

  • 功能:僅在 HTTPS 連線傳送 Cookie。
  • 部署:生產環境必開;本地開發可暫時關閉 (或用 localhost + dotnet dev-certs https --trust)。
  • 注意:若反向代理 (Nginx/Cloudflare) 終止 TLS,後端 HTTP 仍需 Secure=true,並設定 ForwardedHeaders Middleware。

SameSite (CSRF 核心防護)

值行為適用場景
Strict完全禁止跨站請求攜帶 (含導航連結)高安全性 API、管理後台、金融交易
Lax (預設)允許安全跨站導航 (GET 連結),阻擋 POST/iframe大多數網站預設平衡選擇
None允許所有跨站請求 (需同時設 Secure=true)跨域 API、嵌入式 Widget、SSO 跨域登入

現代瀏覽器預設行為:Chrome 80+ / Edge / Firefox 預設 Lax。明確設定避免相依預設值變更。

GDPR / 隱私法規合規

1. 分類 Cookie

  • 必要:Session、CSRF Token、負載均衡 Affinity → IsEssential = true,無需同意即可寫入。
  • 偏好:語系、主題、時區 → 需使用者同意。
  • 統計/分析:GA、Matomo → 需明確同意。
  • 行銷/追蹤:FB Pixel、AdWords → 需明確同意。

2. 同意管理整合 (ASP.NET Core)

// Startup.cs / Program.cs
services.Configure(options =>
{
    options.CheckConsentNeeded = context => true; // 所有非必要 Cookie 需同意
    options.MinimumSameSitePolicy = SameSiteMode.Lax;
    options.Secure = CookieSecurePolicy.Always;
});

app.UseCookiePolicy(); // 必須在 UseAuthentication 之前

// 寫入非必要 Cookie 時檢查同意
if (Context.RequestServices.GetRequiredService()
    .CanTrack)
{
    Response.Cookies.Append("ga_id", "GA1.2.xxx", new CookieOptions { IsEssential = false });
}

3. 前端同意條幅 (參考實作)

<div id="cookie-banner" class="fixed bottom-0 w-full bg-gray-900 text-white p-4">
  本網站使用 Cookie 改善體驗。<button id="accept-all" class="ml-4 btn btn-primary">接受全部</button>
  <button id="accept-essential" class="ml-2 btn btn-outline">僅必要</button>
</div>

<script>
document.getElementById('accept-all').onclick = () => {
  document.cookie = "cookie_consent=all; path=/; max-age=31536000; SameSite=Lax";
  document.getElementById('cookie-banner').remove();
};
document.getElementById('accept-essential').onclick = () => {
  document.cookie = "cookie_consent=essential; path=/; max-age=31536000; SameSite=Lax";
  document.getElementById('cookie-banner').remove();
};
</script>

常見問題 FAQ

Q: 為什麼刪除 Cookie 不生效?
A: Delete 內部是設定 Expires = 過去時間。**Path、Domain、Secure、SameSite 必須與建立時完全一致**,瀏覽器才會匹配並移除。
Q: 子域名無法共享 Cookie?
A: 確認 Domain=.example.com (開頭有點)、SameSite=None; Secure=true (跨域需求)、父域名未設 __Host- 前綴 (禁止 Domain 屬性)。
Q: AJAX 請求不攜帶 Cookie?
A: 前端 fetch(url, { credentials: 'include' }) 或 axios.defaults.withCredentials = true;後端 CORS 必須 AllowCredentials = true 且 AllowOrigins 不能為 `*` (需具體域名)。
Q: `SameSite=None` 在舊版瀏覽器 (iOS 12, Safari 13, Chrome < 76) 失效?
A: 這些瀏覽器將 `None` 視為 `Strict`。解決:User-Agent 偵測舊版瀏覽器時**不輸出 SameSite 屬性** (視為預設 Lax)。
Q: 如何加密 Cookie 內容?
A: ASP.NET Core 內建 CookieAuthenticationOptions 使用 DataProtection 自動加密/簽章。自訂 Cookie 可用 IDataProtector 手動保護。

總結

Cookie 操作看似簡單,實則涉及 安全屬性 (HttpOnly/Secure/SameSite)、作用域、生命週期、法律合規、跨域傳輸 多個維度。現代 ASP.NET Core 專案建議:

  1. 統一使用 CookieOptions 強型別設定,避免字串拼接錯誤。
  2. 認證 Cookie 必開 HttpOnly=true, Secure=true, SameSite=Strict/Lax。
  3. 跨域 SSO 用 SameSite=None, Secure=true, Domain=.parent.com。
  4. 整合 CookiePolicy + 前端同意條幅滿足 GDPR/個資法。
  5. 刪除 Cookie 時完整複製原建立選項。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved