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

ASP.NET Cookie + MD5 實現「記住密碼」功能完整實戰(含安全加固)

     編輯:ASP.NET 基礎

需求與安全基線

  • 用戶勾選「記住密碼」→ 下次自動填充用戶名、密文密碼。
  • 絕不存儲明文密碼:Cookie 僅存 MD5/SHA256 雜值,驗證時比對雜值。
  • 防範 XSS/CSRF:Cookie 設置 HttpOnly=true、Secure=true(HTTPS)、SameSite=Lax。
  • 定期輪換:建議 30 天過期,敏感系統縮短至 7-14 天。

核心實現類

using System;
using System.Web;
using System.Web.Security;

public class RememberMeHelper
{
    private const string UserNameCookieName = "RememberMe_User";
    private const string PasswordHashCookieName = "RememberMe_PwdHash";
    private const int ExpireDays = 30;
    private const string PlaceholderPassword = "◆◆◆◆◆◆◆◆◆◆"; // 10 字符佔位符

    private readonly HttpContext _ctx;
    public RememberMeHelper(HttpContext ctx) { _ctx = ctx; }

    /// 
    /// 登錄成功後調用:根據勾選狀態寫入/清除 Cookie
    /// 
    public void ProcessLogin(string userName, string password, bool rememberMe)
    {
        if (rememberMe)
        {
            SaveCookie(UserNameCookieName, userName);
            // 存儲密碼雜值(MD5 或更強 SHA256)
            string pwdHash = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA256");
            SaveCookie(PasswordHashCookieName, pwdHash);
        }
        else
        {
            ClearCookie(UserNameCookieName);
            ClearCookie(PasswordHashCookieName);
        }
    }

    /// 
    /// 頁面加載時調用:自動填充用戶名、密碼框佔位符
    /// 
    public void AutoFill(ref string userNameBox, ref string passwordBox, ref bool rememberChecked)
    {
        var userCookie = _ctx.Request.Cookies[UserNameCookieName];
        var pwdCookie = _ctx.Request.Cookies[PasswordHashCookieName];

        if (userCookie != null)
        {
            rememberChecked = true;
            userNameBox = userCookie.Value;
            if (pwdCookie != null)
            {
                // 密碼框設置佔位符,前端顯示圓點,實際值不回填明文
                passwordBox = PlaceholderPassword;
            }
        }
    }

    /// 
    /// 登錄驗證時調用:返回用於比對的密碼雜值
    /// 
    public string GetPasswordHashForValidation(string inputPassword, bool rememberChecked)
    {
        if (rememberChecked)
        {
            var pwdCookie = _ctx.Request.Cookies[PasswordHashCookieName];
            if (pwdCookie != null) return pwdCookie.Value; // 直接用 Cookie 雜值比對
        }
        // 未勾選或無 Cookie:現場計算輸入密碼雜值
        return FormsAuthentication.HashPasswordForStoringInConfigFile(inputPassword, "SHA256");
    }

    private void SaveCookie(string name, string value)
    {
        var cookie = new HttpCookie(name, value)
        {
            Expires = DateTime.Now.AddDays(ExpireDays),
            HttpOnly = true,
            Secure = _ctx.Request.IsSecureConnection, // 僅 HTTPS 傳輸
            SameSite = SameSiteMode.Lax
        };
        _ctx.Response.Cookies.Set(cookie);
    }

    private void ClearCookie(string name)
    {
        var cookie = new HttpCookie(name)
        {
            Expires = DateTime.Now.AddDays(-1),
            HttpOnly = true,
            Secure = _ctx.Request.IsSecureConnection,
            SameSite = SameSiteMode.Lax
        };
        _ctx.Response.Cookies.Set(cookie);
    }
}

前端頁面關鍵點

<asp:TextBox ID="txtUserName" runat="server" />
<asp:TextBox ID="txtPassword" runat="server" TextMode="Password" autocomplete="off" />
<asp:CheckBox ID="chkRemember" runat="server" Text="記住密碼" />
<asp:Button ID="btnLogin" runat="server" Text="登錄" OnClick="btnLogin_Click" />

後端調用流程

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string user = "", pwd = "";
        bool remember = false;
        new RememberMeHelper(Context).AutoFill(ref user, ref pwd, ref remember);
        txtUserName.Text = user;
        txtPassword.Text = pwd; // 佔位符
        chkRemember.Checked = remember;
    }
}

protected void btnLogin_Click(object sender, EventArgs e)
{
    string inputUser = txtUserName.Text.Trim();
    string inputPwd = txtPassword.Text;
    bool remember = chkRemember.Checked;

    // 關鍵:若密碼框是佔位符,說明用戶未修改密碼,直接用 Cookie 雜值驗證
    bool useCookieHash = (inputPwd == RememberMeHelper.PlaceholderPassword);

    var helper = new RememberMeHelper(Context);
    string hashToValidate = useCookieHash
        ? helper.GetPasswordHashForValidation(null, true) // 內部會讀 Cookie
        : FormsAuthentication.HashPasswordForStoringInConfigFile(inputPwd, "SHA256");

    // 數據庫驗證:SELECT * FROM Users WHERE UserName=@u AND PasswordHash=@h
    bool valid = ValidateUser(inputUser, hashToValidate);

    if (valid)
    {
        helper.ProcessLogin(inputUser, inputPwd, remember);
        Response.Redirect("Default.aspx");
    }
    else
    {
        lblMsg.Text = "用戶名或密碼錯誤";
        // 登錄失敗時清除佔位符,避免下次誤判
        txtPassword.Text = "";
    }
}

安全增強清單

措施實現
升級雜值算法替換 MD5 → SHA256 / PBKDF2 / Argon2(需引入庫)
綁定設備指紋Cookie 值 = Hash(UserId + PasswordHash + UserAgent + IP段)
異常登錄告警新設備/地點登錄發送郵件/短信確認
Token 化改造引入 Refresh Token + Access Token,替換 Cookie 方案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved