C#登录表单,登录按钮,安全性

ahm*_*t93 1 c# database forms security login

因此,我是VS和C#的新手,我自学成才,以更好地了解与我一起使用的产品的后端。我创建了一个小型数据库,其中包含一些信息和一个“登录”表单。一切似乎都可以正确编译,但是这是安全的方法,或者还有另一种方法,可以提供任何帮助。谢谢。

 private void button2_Click(object sender, EventArgs e)
    {

        SqlCommand cmd = new SqlCommand("select * from tbladmin where username=@username and password=@password", sqlcon);
        cmd.Parameters.AddWithValue("@username", txtusername.Text);
        cmd.Parameters.AddWithValue("@password", txtpassword.Text);
        SqlDataAdapter sda = new SqlDataAdapter(cmd);
        DataTable dtbl = new DataTable();
        sda.Fill(dtbl);


        try
        {

            if (dtbl.Rows.Count > 0)
            {
                if (dtbl.Rows[0]["role"].ToString() == "Admin")
                {
                    SqlCommand cmd2 = new SqlCommand("select date from tbladmin where username=@username and password=@password", sqlcon);
                    cmd2.Parameters.AddWithValue("@username", txtusername.Text);
                    cmd2.Parameters.AddWithValue("@password", txtpassword.Text);
                    SqlDataAdapter sda2 = new SqlDataAdapter(cmd2);
                    DataTable dss = new DataTable();
                    sda2.Fill(dss);
                    String value2 = dss.Rows[0][0].ToString();
                    DateTime date = DateTime.Parse(dss.Rows[0][0].ToString());
                    Class1.Txtusername = txtusername.Text;
                    Debug.WriteLine("value is :   " + value2);

                    if (date.AddDays(90) < DateTime.Now)
                    {
                        Changpassad obj2 = new Changpassad();
                        this.Hide();
                        obj2.Show();
                    }
                    else
                    {

                        calladmin obj = new calladmin(dss.Rows[0][0].ToString());
                        this.Hide();
                        obj.Show();
                    }
                }
            }
            else if (dtbl.Rows.Count == 0)
            {
                SqlCommand cmd3 = new SqlCommand("select date from tblcallcenter where username=@username and password=@password", sqlcon);
                cmd3.Parameters.AddWithValue("@username", txtusername.Text);
                cmd3.Parameters.AddWithValue("@password", txtpassword.Text);
                SqlDataAdapter sda2 = new SqlDataAdapter(cmd3);
                DataTable dss = new DataTable();
                sda2.Fill(dss);
                String value2 = dss.Rows[0][0].ToString();
                DateTime date = DateTime.Parse(dss.Rows[0][0].ToString());

                Debug.WriteLine("value is :   " + value2);

                if (date.AddDays(90) < DateTime.Now)
                {
                    Changpass obj2 = new Changpass()/;
                    this.Hide();
                    obj2.Show();
                }
                else
                {
                    SqlCommand cmd4 = new SqlCommand("select user_id , username from tblcallcenter where username=@username and password=@password", sqlcon);
                    cmd4.Parameters.AddWithValue("@username", txtusername.Text);
                    cmd4.Parameters.AddWithValue("@password", txtpassword.Text);
                    SqlDataAdapter From_sda = new SqlDataAdapter(cmd4);
                    DataTable From_ds = new DataTable();
                    From_sda.Fill(From_ds);
                    String value1 = From_ds.Rows[0][1].ToString();
                    int id = int.Parse(From_ds.Rows[0][0].ToString());

                    Debug.WriteLine("value is :   " + value1);
                    Class1.Txtusername = txtusername.Text;
                    this.Hide();
                    SqlCommand cmd5 = new SqlCommand("select  [from], Take from tblcallcenter where username=@username and password=@password", sqlcon);
                    cmd5.Parameters.AddWithValue("@username", txtusername.Text);
                    cmd5.Parameters.AddWithValue("@password", txtpassword.Text);
                    SqlDataAdapter sda1 = new SqlDataAdapter(cmd5);
                    DataTable ds = new DataTable();
                    sda1.Fill(ds);
                    Callcenter1 obj = new Callcenter1(ds.Rows[0][0].ToString(), ds.Rows[0][1].ToString());
                    this.Hide();
                    obj.Show();
                }
            }

            else
            {
                MessageBox.Show("Invalid Login try checking Useraname Or Password !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        catch (Exception)
        {
            MessageBox.Show("Invalid Login try checking Useraname Or Password !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
Run Code Online (Sandbox Code Playgroud)

Jus*_*ard 8

1.不要忘记单一责任原则

您的表单仅负责UI演示。您的表格是否应该知道如何存储数据?您的表格有责任知道用户何时应更改密码吗?没有。

每个班级应负一个责任。您可能有一个AuthenticationService负责验证用户身份的UserRepository类,以及一个用于在数据库中存储/检索用户的类。例如,这可能是您的button2点击处理程序:

private void button2_Click(object sender, EventArgs e)
{
    var authenticationService = new AuthenticationService(sqlcon);


    try
    {
        var user = authenticationService.AuthenticateUser(txtusername.Text, txtpassword.Text);

        if (user.Date.AddDays(90) < DateTime.UtcNow)
        {
            Changpassad obj2 = new Changpassad();
            this.Hide();
            obj2.Show();

            return;
        }

        if (user.IsAdmin)
        {
            calladmin obj = new calladmin(user);
            this.Hide();
            obj.Show();
        }
        else
        {
            Callcenter1 obj = new Callcenter1(user);
            this.Hide();
            obj.Show();
        }

    }
    catch (Exception)
    {
        MessageBox.Show("Invalid Login try checking Useraname Or Password !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以进一步推广该原理,并使您的方法也负有单一责任。例如,在上面的代码中,我仍然提取代码以检查是否需要更改密码以及负责打开正确表单的代码。

您已经在SQL查询中使用了参数。好。您可以抵抗SQL注入

熟悉后,我还建议您研究诸如Entity Framework之类的ORM,以简化流程。


2.不要在数据库中存储明文密码

说真的 绝对不要那样做。

始终尝试避免管理用户密码。如果绝对必须,.Net框架中有内置类可以处理此问题。这是一些链接,但是快速搜索应该会得到更多。

如果由于某些原因您不使用这些文件并决定自己管理密码。您需要找到一种加密安全的哈希算法(而不是其他答案中的md5)。而且,您需要为散列的每个密码使用唯一的“盐”。我将这些链接留在这里,因为它超出了您当前问题的范围:

- 哈希密码在ASP.NET核心 - 编码,加密和哈希的区别


3.给您的变量起重要的名字。

什么button2啊 什么obj2啊 什么是ds.Rows[0][0].ToString()代表?您应该尝试为变量指定代表名称。怎么样btnLogincallAdminForm...

当我们在这里时,我建议您阅读C#通用命名约定。例如,类的命名约定为PascalCase。应该CallAdmin不会calladmin


4.为什么要将用户名/密码存储在多个表中?

为什么将用户存储在tbladmin和中tblcallcenter

tblUsers指定用户角色的单个,一列或相关表如何?从长远来看,这将更易于维护。为什么一次只能做两次?