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

时间:2011-03-02 21:32:07

标签: c# forms login username

好吧,我正在为游戏设置一个简单的登录界面,它使用用户名和密码验证。它连接到数据库检查以查看是否存在用户名和密码,然后查看它是否与数据匹配。如果您插入正确的用户名和密码,它可以正常工作,但如果您执行的操作不在数据库中,则会失败并崩溃。我想知道我这样做了吗?代码如下。

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!");
   }
}

如果插入错误,则不会显示错误的USER / PASS框。

5 个答案:

答案 0 :(得分:4)

  1. 您要从查询中返回两件事,而不是一件。
  2. ExecuteScalar正在返回null。检查您的拼写和数据库。
  3. 在您的数据库中保留明文密码至少是......味道不好。
  4. 祈祷你永远不会见到先生。 ' or 1=1--(此处插入强制性xkcd链接)

答案 1 :(得分:2)

首先:About Sql Injection Attacks

你应该在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方法时会抛出空引用异常。通过切换它们,usernameBox.Text将不为null,并且如果bba[1]为空,则从Text属性调用Equals将导致错误比较。

答案 2 :(得分:0)

由于您在查询中检查用户名和密码,因此如果用户名/ passowrd不正确,则不会有任何结果。

我会选择

            var result = command.ExecuteScalar();
            my.Close();


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

            }

答案 3 :(得分:0)

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

另外,引用bba [1] .Equals()假设数组的该元素中存在一个实例。如果它为null,则会得到NullRefException。在进行等于检查之前,您应该检查null:

if (bba[1] != null && bba[1].Equals(usernameBox.Text))

答案 4 :(得分:0)

几点意见:

  • 不要将SQL查询串在一起 - 使用参数化查询来避免SQL注入
  • 您应该将SqlConnectionSqlCommand放入using(....) { ... }
  • 如果您返回两个值,则不应使用.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,该方法将用户名和密码作为字符串接收,并返回例如bool
  • 从您的事件处理程序,从UI获取信息(读出文本框),使用这些值调用该单独的函数,然后处理返回的值

但混合用户界面,逻辑和数据访问代码 - 它变得混乱,维护噩梦真的很快!