登入頁需「記住帳號」功能:勾選後將使用者名稱寫入 Cookie,下次自動填入。使用 FormsAuthentication 搭配自訂 Cookie 時,踩中三大坑:驗證衝突、中文亂碼、刪除無效。
先寫入 Response.Cookies["UserName"],再呼叫 FormsAuthentication.SetAuthCookie,導致登入失敗、導回登入頁,且 Cookie 值變亂碼。
FormsAuthentication 內部同樣寫入名為 .ASPXAUTH 的 Cookie,若應用程式同名 Cookie 先寫入,ASP.NET 偵測到「疑似竄改」拒絕驗證。
// 正確順序
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));
}
}
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;
}
}
}
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。
不設定 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);
FormsAuthentication 優先,自訂 Cookie 其次。escape() (JS) vs UrlEncode (.NET) 不匹配。Expires = 過去時間,勿用 Remove。HttpOnly=true、Secure=true (HTTPS)、SameSite=Lax/Strict 防禦 XSS/CSRF。cookie.Path = "/" 確保全站可見。Cookie 看似簡單,實則暗藏 FormsAuthentication 互動順序、編碼標準、刪除機制、安全屬性等細節。掌握上述四大鐵律,即能打造穩健、安全、支援中文的「記住我」與自訂 Cookie 功能。