Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查数据库密码C后程序崩溃#_C#_Forms_Authentication - Fatal编程技术网

C# 检查数据库密码C后程序崩溃#

C# 检查数据库密码C后程序崩溃#,c#,forms,authentication,C#,Forms,Authentication,我正在为一个游戏开发一个简单的登录屏幕,它使用用户名和密码验证。它连接到数据库,检查用户名和密码是否存在,然后查看是否与数据匹配。如果您插入了正确的用户名和密码,它可以正常工作,但是如果您插入了数据库中没有的用户名和密码,它就会失败并崩溃。我想知道我做得对吗?代码如下 private void loginButton_Click(object sender, EventArgs e) { string connectionString = "datasource=STUFFZ;databa

我正在为一个游戏开发一个简单的登录屏幕,它使用用户名和密码验证。它连接到数据库,检查用户名和密码是否存在,然后查看是否与数据匹配。如果您插入了正确的用户名和密码,它可以正常工作,但是如果您插入了数据库中没有的用户名和密码,它就会失败并崩溃。我想知道我做得对吗?代码如下

private void loginButton_Click(object sender, EventArgs e)
{
   string connectionString = "datasource=STUFFZ;database=users";
   string select = "SELECT Username, Password FROM RegularUsers WHERE Username = '" + usernameBox.Text + "' AND Password = '" + passwordBox.Text + "'";

   MySqlConnection my = new MySqlConnection(connectionString);

   MySqlCommand command = new MySqlCommand(select, my);
   my.Open();

   //String strResult = String.Empty;
   //strResult = (String)command.ExecuteScalar();
   string[] bba = new string[2];
   bba[1] = (String)command.ExecuteScalar();
   my.Close();

   if (bba[1].Equals(usernameBox.Text))
   {
      AdminPanel bb = new AdminPanel();
      bb.Show();
   }
   else
   {
      MessageBox.Show("INCORRECT USER/PASS!");
   }
}
如果插入错误,则不会显示错误的用户/密码框

首先:

您应该将逻辑封装在try-catch块中。您缺少引发的异常,因此它正在中止程序

try
{
    string connectionString = "datasource=STUFFZ;database=users";
    string select = "SELECT Username, Password FROM RegularUsers WHERE 
        Username = '" + usernameBox.Text + "' 
        AND Password = '" + passwordBox.Text + "'";

      MySqlConnection my = new MySqlConnection(connectionString);

      MySqlCommand command = new MySqlCommand(select, my);
            my.Open();

            //String strResult = String.Empty;
            //strResult = (String)command.ExecuteScalar();
            string[] bba = new string[2];
            bba[1] = (String)command.ExecuteScalar();
            my.Close();


            if (bba[1].Equals(usernameBox.Text))
            {
                AdminPanel bb = new AdminPanel();
                bb.Show();
            }
}
catch(Exception ex)
{
 //MessageBox.Show(ex.Message); //Will show what the exception message is.
    MessageBox.Show("INCORRECT USER/PASS!");
}
我相信这就是你的问题所在:

 if (bba[1].Equals(usernameBox.Text))
切换到以下位置:

  if (usernameBox.Text.Equals(bba[1]))
原因是,如果
bba[1]
为null,则在尝试使用Equals方法时会引发null引用异常。通过切换它们,
usernameBox.Text
不会为null,如果
bba[1]
为null,则从Text属性调用Equals只会导致错误的比较

  • 您从查询中返回了两个内容,而不是一个
  • ExecuteScalar
    正在返回
    null
    。检查拼写和数据库
  • 在数据库中保留明文密码是。。。至少品味不好
  • 祈祷你永远不会遇到
    ”先生或1=1--
    (在此处插入强制性的xkcd链接)

  • 由于您在查询中检查用户名和密码,因此在用户名/密码不正确的情况下不会有任何结果

    我只想和你一起去

                var result = command.ExecuteScalar();
                my.Close();
    
    
                if (result !=null )
                {
                    AdminPanel bb = new AdminPanel();
                    bb.Show();
                }
                else
                {
                    MessageBox.Show("INCORRECT USER/PASS!");
    
                }
    

    好吧,如果这是我的项目,我就不会使用ExsecuteScalar来获取一条SQL语句的结果,该语句给了我不止一个字段的返回。可以使用Exists子句返回“Y”,也可以使用Count返回数字。基本上,您只想知道存在使用此用户名和密码的用户记录

    此外,引用bba[1].Equals()时,假定数组的该元素中存在实例。如果为null,则得到NullRefException。在执行等于检查之前,应先检查null:

    if (bba[1] != null && bba[1].Equals(usernameBox.Text))
    
    几点意见:

    • 不要将SQL查询串在一起-使用参数化的查询来避免SQL注入
    • 您应该使用(..){…}块将
      SqlConnection
      SqlCommand
      放入
    • 如果返回两个值,则不应使用
      .ExecuteScalar()
      -该调用仅适用于单行、单列返回
    总而言之,您的代码应该是这样的:

    private void loginButton_Click(object sender, EventArgs e)
    {
       string connectionString = "datasource=STUFFZ;database=users";
       string select = "SELECT Username, Password FROM dbo.RegularUsers " + 
                       "WHERE Username = @user AND Password = @Pwd"
    
       using(MySqlConnection myConn = new MySqlConnection(connectionString))
       using(MySqlCommand command = new MySqlCommand(select, myConn))
       { 
           command.Parameters.Add("@user", SqlDbType.VarChar, 50);
           command.Parameters["@user"].Value = usernameBox.Text.Trim();
    
           command.Parameters.Add("@pwd", SqlDbType.VarChar, 50);
           command.Parameters["@pwd"].Value = passwordBox.Text.Trim();
    
           myConn.Open();
    
           using(SqlDataReader rdr = command.ExecuteReader())
           {
              if(rdr.Read())
              {
                 string userName = rdr.GetString(0);
                 string password = rdr.GetString(1);
    
                 rdr.Close();
    
                 // here compare those values and do whatever you need to do
              }
           }
    
           myConn.Close();
       }    
    }
    
    此外,我认为这段代码有点凌乱,因为您在同一段代码中进行数据访问(从SQL Server中选择)和UI访问(读取文本框、弹出对话框)-

    你应该争取更多的关注点分离,例如

    • 定义一个方法
      CheckUserName
      ,该方法接受用户名和密码作为字符串,并返回例如a
      bool
    • 从事件处理程序中,从UI获取信息(读取文本框),使用这些值调用单独的函数,然后处理返回的值
    但是混合了用户界面、逻辑和数据访问代码——很快就会变得一团糟,成为维护的噩梦

    您确实需要查找sql注入。