首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# ComboBox 角色驗證登錄邏輯:SQL 參數化查詢與狀態比對最佳實踐

     編輯:程式設計綜合問答

原代碼問題

  • SQL 拼接字符串 → **SQL 注入風險**。
  • 查詢返回後未讀取 status 字段,直接用變量 status (未定義) 比較。
  • 邏輯分支重複,未處理「用戶名密碼正確但角色不匹配」情況。

修正後完整代碼 (WinForms + ADO.NET)

private void btnLogin_Click(object sender, EventArgs e) {
    // 1. 前端驗證
    if (string.IsNullOrWhiteSpace(txtUserName.Text) ||
        string.IsNullOrWhiteSpace(txtPassword.Text)) {
        MessageBox.Show("用戶名和密碼不能為空");
        return;
    }
    string role = cmbRole.SelectedItem?.ToString();
    if (string.IsNullOrEmpty(role)) {
        MessageBox.Show("請選擇角色");
        return;
    }

    // 2. 參數化查詢
    const string sql = @"
        SELECT user_name, status 
        FROM user_info 
        WHERE user_name = @user AND user_pwd = @pwd";
    
    using (var conn = new SqlConnection(connStr))
    using (var cmd = new SqlCommand(sql, conn)) {
        cmd.Parameters.AddWithValue("@user", txtUserName.Text.Trim());
        cmd.Parameters.AddWithValue("@pwd", txtPassword.Text.Trim()); // 實際應存哈希值!
        
        try {
            conn.Open();
            using (var reader = cmd.ExecuteReader()) {
                if (!reader.Read()) {
                    MessageBox.Show("用戶名或密碼錯誤");
                    return;
                }
                
                string dbRole = reader["status"].ToString(); // 讀取數據庫角色
                if (!string.Equals(dbRole, role, StringComparison.OrdinalIgnoreCase)) {
                    MessageBox.Show($"該賬號角色為「{dbRole}」,無法以「{role}」身份登錄");
                    return;
                }
                
                // 3. 角色匹配,跳轉對應窗體
                Form targetForm = role switch {
                    "管理員" => new AdminForm(),
                    "學生" => new StudentForm(),
                    _ => null
                };
                
                if (targetForm != null) {
                    this.Hide();
                    targetForm.ShowDialog();
                    this.Close();
                }
            }
        } catch (Exception ex) {
            MessageBox.Show("登錄異常:" + ex.Message);
        }
    }
}

關鍵改進點

項目原代碼修正版
SQL 執行 字符串拼接 參數化 @user, @pwd
角色比對 變量 status 未賦值 reader["status"] 讀取數據庫值
密碼存儲 明文 **必須存 BCrypt/Argon2 哈希**,驗證時 BCrypt.Verify(input, hash)
資源釋放 手動 Close() 易漏 using 自動 Dispose
窗體跳轉 重複 new Form Switch 表達式統一

進階:密碼哈希驗證 (BCrypt.Net-Next)

// 註冊/修改密碼時
string hash = BCrypt.Net.BCrypt.HashPassword(plainPassword, workFactor: 12);
// 存入 user_pwd 字段

// 登錄驗證時
string storedHash = reader["user_pwd"].ToString();
if (!BCrypt.Net.BCrypt.Verify(txtPassword.Text, storedHash)) {
    MessageBox.Show("用戶名或密碼錯誤");
    return;
}

總結

登錄邏輯核心:**參數化查詢防注入 + 讀取數據庫角色字段比對 + 密碼哈希驗證 + 統一窗體跳轉**。切勿在 SQL 中拼接用戶輸入,切勿明文存儲密碼。

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