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

ASP.NET Cookie 傳遞參數完整指南:建立、讀取、刪除與安全性最佳實踐

     編輯:關於ASP.NET

Cookie 是 ASP.NET 在用戶端儲存少量資料的經典機制,常用於記住登入狀態、用戶偏好、跨頁面傳遞簡單參數。本文詳細說明 `HttpCookie` 類別操作、編碼處理、安全性屬性、SameSite 政策與現代替代方案。

核心操作:建立、寫入、讀取、刪除

1. 建立與寫入 Cookie (伺服器 → 用戶端)

// 基本寫入
HttpCookie cookie = new HttpCookie("UserPreferences");
cookie.Value = "theme=dark&lang=zh-TW&fontSize=14";
cookie.Expires = DateTime.Now.AddDays(30); // 30 天後過期
Response.Cookies.Add(cookie);

// 進階安全設定 (推薦生產環境)
HttpCookie secureCookie = new HttpCookie("AuthToken", encryptedToken);
secureCookie.Expires = DateTime.Now.AddHours(2);
secureCookie.HttpOnly = true;      // 防止 JavaScript 存取 (防 XSS)
secureCookie.Secure = true;        // 僅 HTTPS 傳輸 (需 SSL)
secureCookie.SameSite = SameSiteMode.Strict; // 防 CSRF (ASP.NET 4.7.2+)
secureCookie.Domain = ".example.com"; // 跨子域共享 (可選)
Response.Cookies.Add(secureCookie);

2. 讀取 Cookie (用戶端 → 伺服器)

// 安全讀取模式
string GetCookieValue(string name, string defaultValue = "")
{
    HttpCookie cookie = Request.Cookies[name];
    if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
    {
        return HttpUtility.UrlDecode(cookie.Value); // 解碼
    }
    return defaultValue;
}

// 使用範例
string theme = GetCookieValue("UserPreferences", "theme=light"); // 解析自行處理
string authToken = GetCookieValue("AuthToken");

3. 刪除 Cookie (設定過期時間為過去)

// 標準刪除方式
if (Request.Cookies["UserPreferences"] != null)
{
    HttpCookie cookie = new HttpCookie("UserPreferences");
    cookie.Expires = DateTime.Now.AddDays(-1); // 過去時間
    cookie.Path = "/"; // 必須與建立時相同
    Response.Cookies.Add(cookie);
}

// 擴充方法
public static void DeleteCookie(this HttpResponse response, string name, string path = "/", string domain = null)
{
    var cookie = new HttpCookie(name) { Expires = DateTime.Now.AddDays(-1), Path = path };
    if (domain != null) cookie.Domain = domain;
    response.Cookies.Add(cookie);
}

// 使用
Response.DeleteCookie("AuthToken");

Cookie 完整屬性解析

屬性說明預設值安全建議
NameCookie 名稱 (唯一鍵)-避免敏感詞彙、使用前綴區分功能
Value字串值 (需 URL 編碼)-不存放敏感資料、長度 < 4KB
Expires過期時間 (DateTime.MinValue = Session Cookie)Session設定合理過期、避免永久
Domain適用網域當前網域子域共享設 `.example.com`、謹慎使用
Path適用路徑/限制最小路徑範圍
HttpOnly禁止 JS 存取false必須 true (除非需 JS 讀取)
Secure僅 HTTPS 傳輸false生產環境必須 true
SameSite跨站請求攜帶策略Lax (新版)Strict/Lax/None (跨域需 None+Secure)

SameSite 屬性深度解析 (ASP.NET 4.7.2 / .NET Core 2.1+)

模式行為適用場景注意事項
Strict完全禁止跨站攜帶 (含連結點擊)高安全性功能 (轉帳、刪除)用戶從外部連結進入需重新登入
Lax允許安全跨站 (GET 連結、表單)大多數認證 Cookie (推薦預設)平衡安全與體驗
None允許所有跨站攜帶跨域 API、嵌入式 iframe必須搭配 Secure=true
// 設定 SameSite (需 .NET 4.7.2+ 或使用反射相容舊版)
cookie.SameSite = SameSiteMode.Lax;

// 舊版專案相容寫法 (透過反射)
typeof(HttpCookie).GetProperty("SameSite")?.SetValue(cookie, SameSiteMode.Lax);

實務場景範例

1. 記住登入狀態 (表單認證票據)

// 登入成功後
var ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, 
    DateTime.Now.AddDays(rememberMe ? 30 : 1), rememberMe, userData);
string encTicket = FormsAuthentication.Encrypt(ticket);

var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
{
    HttpOnly = true,
    Secure = Request.IsSecureConnection,
    SameSite = SameSiteMode.Lax,
    Path = FormsAuthentication.FormsCookiePath
};
Response.Cookies.Add(cookie);

2. 購物車商品 ID 清單 (客戶端暫存)

// 加入商品
public void AddToCart(int productId)
{
    var cookie = Request.Cookies["CartItems"] ?? new HttpCookie("CartItems");
    var ids = cookie.Value.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
    if (!ids.Contains(productId)) ids.Add(productId);
    cookie.Value = string.Join(",", ids);
    cookie.Expires = DateTime.Now.AddDays(7);
    Response.Cookies.Add(cookie);
}

// 讀取購物車
public List GetCartItems()
{
    var cookie = Request.Cookies["CartItems"];
    return cookie?.Value.Split(',', StringSplitOptions.RemoveEmptyEntries)
        .Select(int.Parse).ToList() ?? new List();
}

3. 多語言/地區偏好設定

// 設定語言
Response.Cookies.Add(new HttpCookie("Culture", "zh-TW") 
{ 
    Expires = DateTime.Now.AddYears(1), 
    HttpOnly = true, 
    SameSite = SameSiteMode.Lax 
});

// 全域套用 (Global.asax)
protected void Application_BeginRequest()
{
    string culture = Request.Cookies["Culture"]?.Value;
    if (!string.IsNullOrEmpty(culture))
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
        Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
    }
}

安全性最佳實踐清單

  1. 敏感資料禁存 Cookie:密碼、Token、個資、信用卡號 → 用 Session/Server-side Storage
  2. HttpOnly = true:防 XSS 竊取 Session ID、認證 Token
  3. Secure = true:生產環境強制 HTTPS,防中間人攻擊
  4. SameSite = Lax/Strict:防 CSRF,現代瀏覽器預設 Lax
  5. 加密 Cookie 值:`MachineKey.Protect/Unprotect` 或 AES 加密
  6. 設定合理過期:避免 Session Cookie 敏感操作、持久 Cookie 定期輪換
  7. 限制 Domain/Path:最小權限原則
  8. 定期審計 Cookie:清理過期、無用、過大 Cookie

現代替代方案對比

方案儲存位置容量自動攜帶適用場景
Cookie用戶端4KB是 (每請求)身份識別、輕量偏好、追蹤
Session伺服器端無上限 (記憶體)透過 Cookie 傳 SessionID用戶狀態、購物車、權限暫存
LocalStorage用戶端 (JS)5-10MB否 (需 JS 手動)大量客戶端資料、離線快取
SessionStorage用戶端 (JS)5-10MB否 (分頁隔離)單一會話暫存資料
IndexedDB用戶端 (JS)數百 MB否結構化離線資料、PWA
JWT (Authorization Header)用戶端 (記憶體)~8KB否 (JS 手動附加)無狀態 API 認證、微服務

編碼處理提醒

// 寫入時編碼
cookie.Value = HttpUtility.UrlEncode("包含中文&特殊字元=值");

// 讀取時解碼
string value = HttpUtility.UrlDecode(cookie.Value);

// 或使用 Base64 避免編碼問題
cookie.Value = Convert.ToBase64String(Encoding.UTF8.GetBytes(originalString));
string decoded = Encoding.UTF8.GetString(Convert.FromBase64String(cookie.Value));

Cookie 雖屬經典技術,但在身份認證、個人化偏好、輕量狀態傳遞仍扮演關鍵角色。掌握 `HttpCookie` 完整屬性、安全性屬性 (HttpOnly/Secure/SameSite)、編碼處理與現代替代方案選擇,能構建安全、相容、可維護的用戶端狀態管理方案。

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