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

ASP.NET Cookie 進階實戰:FormsAuthentication 衝突、中文編碼、正確刪除與 Session Cookie

     編輯:.NET 實例教學

情境

登入頁需「記住帳號」功能:勾選後將使用者名稱寫入 Cookie,下次自動填入。使用 FormsAuthentication 搭配自訂 Cookie 時,踩中三大坑:驗證衝突、中文亂碼、刪除無效。

坑 1:FormsAuthentication 與同名 Cookie 衝突

現象

先寫入 Response.Cookies["UserName"],再呼叫 FormsAuthentication.SetAuthCookie,導致登入失敗、導回登入頁,且 Cookie 值變亂碼。

根因

FormsAuthentication 內部同樣寫入名為 .ASPXAUTH 的 Cookie,若應用程式同名 Cookie 先寫入,ASP.NET 偵測到「疑似竄改」拒絕驗證。

解決:先驗證、後寫入自訂 Cookie


// 正確順序
protected void btnLogin_Click(object sender, EventArgs e)
{
    if (ValidateUser(txtUser.Text, txtPwd.Text))
    {
        // 1. 先建立驗證票證
        FormsAuthentication.SetAuthCookie(txtUser.Text, false);

        // 2. 再寫入「記住帳號」Cookie
        if (chkRemember.Checked)
        {
            var cookie = new HttpCookie("RememberMe")
            {
                Value = HttpUtility.UrlEncode(txtUser.Text, Encoding.GetEncoding("gb2312")),
                Expires = DateTime.Now.AddMonths(1)
            };
            Response.Cookies.Add(cookie);
        }
        else
        {
            // 取消記住 → 刪除 Cookie
            DeleteCookie("RememberMe");
        }

        Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUser.Text, false));
    }
}

坑 2:中文 Cookie 值亂碼

原因

Cookie 標準僅支援 ASCII,中文需編碼。瀏覽器/伺服器預設編碼不一致導致亂碼。

統一編碼策略

  • 寫入:HttpUtility.UrlEncode(value, Encoding.GetEncoding("gb2312")) 或 Encoding.UTF8(前後端一致即可)。
  • 讀取:HttpUtility.UrlDecode(cookie.Value, Encoding.GetEncoding("gb2312"))。

讀取並自動填入


protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var cookie = Request.Cookies["RememberMe"];
        if (cookie != null)
        {
            txtUser.Text = HttpUtility.UrlDecode(cookie.Value, Encoding.GetEncoding("gb2312"));
            chkRemember.Checked = true;
        }
    }
}

坑 3:Cookie 刪除無效

錯誤做法


Response.Cookies.Remove("RememberMe"); // 僅移除伺服器集合,瀏覽器仍保留

正確做法:設定過期時間為過去


private void DeleteCookie(string name)
{
    if (Response.Cookies[name] != null)
    {
        Response.Cookies[name].Expires = DateTime.Now.AddDays(-1);
    }
}

瀏覽器收到 Set-Cookie: RememberMe=...; Expires=過去時間 即會刪除對應 Cookie。

補充:Session Cookie(瀏覽器關閉即失效)

不設定 Expires / Max-Age:


var sessionCookie = new HttpCookie("TempData", value); // 無 Expires
Response.Cookies.Add(sessionCookie);

關閉瀏覽器進程即自動銷毀,適合暫時性追蹤資料。

完整關鍵代碼彙總


// 登入:先驗證後寫入
FormsAuthentication.SetAuthCookie(userName, false);
if (remember)
{
    Response.Cookies.Add(new HttpCookie("RememberMe")
    {
        Value = HttpUtility.UrlEncode(userName, Encoding.GetEncoding("gb2312")),
        Expires = DateTime.Now.AddMonths(1)
    });
}
else
{
    DeleteCookie("RememberMe");
}

// 讀取
if (Request.Cookies["RememberMe"] != null)
    txtUser.Text = HttpUtility.UrlDecode(Request.Cookies["RememberMe"].Value, Encoding.GetEncoding("gb2312"));

// 刪除
void DeleteCookie(string name) 
    => Response.Cookies[name]?.Expires = DateTime.Now.AddDays(-1);

最佳實務總結

  1. 順序鐵律:FormsAuthentication 優先,自訂 Cookie 其次。
  2. 編碼統一:全站採用 UTF-8 或 GB2312,前後端一致,避免 escape() (JS) vs UrlEncode (.NET) 不匹配。
  3. 刪除模式:Expires = 過去時間,勿用 Remove。
  4. 安全屬性:生產環境務必加上 HttpOnly=true、Secure=true (HTTPS)、SameSite=Lax/Strict 防禦 XSS/CSRF。
  5. 路徑統一:cookie.Path = "/" 確保全站可見。

結語

Cookie 看似簡單,實則暗藏 FormsAuthentication 互動順序、編碼標準、刪除機制、安全屬性等細節。掌握上述四大鐵律,即能打造穩健、安全、支援中文的「記住我」與自訂 Cookie 功能。

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