【问题标题】:WHERE Name='{NameInput.Text}' AND Password='{GetHashString(PasswordInput.Text)} not workingWHERE Name='{NameInput.Text}' AND Password='{GetHashString(PasswordInput.Text)} 不起作用
【发布时间】:2023-03-05 07:43:01
【问题描述】:

我正在尝试让我的 LoginButton 工作,但它并没有真正做到我想要它做的事情。 我已经有一个 RegisterButton 可以完美运行并且可以毫无问题地创建帐户,但是当尝试执行我的 LoginButton 时,它会连接到数据库,但并没有真正使用 selectQuery 检查帐户是否存在,它应该将 WarningLabel.Text 更改为"Wrong Name or Password"。它确实经历了第一次尝试并将WarningLabel.Text更改为"Welcome " + NameInput.Text;

private void LoginButton_Click(object sender, System.EventArgs e)
{
    string selectQuery = $"SELECT * FROM bank.user WHERE Name='{NameInput.Text}' AND Password='{GetHashString(PasswordInput.Text)}';";
    MySqlCommand cmd;

    connection.Open();
    cmd = new MySqlCommand(selectQuery, connection);
    try
    {
        cmd.ExecuteNonQuery();
        WarningLabel.Text = "Welcome " + NameInput.Text;
    } catch
    {
    WarningLabel.Text = "Wrong Name or Password";
    }

    connection.Close();
} 

最好的问候 - Nebula.exe

【问题讨论】:

  • 如果没有选择记录,为什么会出现异常?
  • 选择查询不会产生错误。您必须检查记录是否已返回。
  • 没有选择记录是什么意思?

标签: c# mysql sql


【解决方案1】:

您应该检查是否有返回记录。 cmd.ExecuteNonQuery(); 不会告诉您是否返回记录,因为它只会执行查询。您应该使用 ExecuteScalar 或 MySQL 数据阅读器 ExecuteReader 并跟踪结果。

注意:您的代码容易出现SQL Injections,您可能希望在查询中使用Parameters,例如@name@password

你的查询是这样的。

string selectQuery = $"SELECT IFNULL(COUNT(*),0) FROM bank.user WHERE Name=@name AND Password=@password;";

然后使用参数

cmd.parameters.AddWithValue(@name, NameInput.Text);
cmd.parameters.AddWithValue(@password, GetHashString(PasswordInput.Text));

然后验证查询是否返回结果

If cmd.ExecuteScalar() > 0
//If count is > 0 then Welcome
//Else Wrong username or password
End If

【讨论】:

  • 公平地说,只有 Name 容易受到 SQL 注入攻击,Password 列不会,因为不会使用直接输入(注意对 GetHashString 函数的调用)
  • @Cleptus Oww 是的,我就是这个意思,谢谢你的关注。
【解决方案2】:

ExecuteNonQuery不打算与返回数据的SQL语句一起使用,您应该使用ExecuteReaderExecuteScalar,您可以查看MySqlCommand.ExecuteReader documentation

警告:您的代码在这部分 SQL 语句中确实存在 SQL 注入漏洞Name='{NameInput.Text}' 检查此SQL Injection explanation

使用示例(来自文档,稍作修改):

using (MySqlConnection myConnection = new MySqlConnection(connStr)) 
{
    using (MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection))
    {
         myConnection.Open();
         MySqlDataReader myReader = myCommand.ExecuteReader();
         while (myReader.Read())
         {
             Console.WriteLine(myReader.GetString(0));
         }
    }
}

【讨论】:

  • 谢谢,这有帮助,所有的人都珍惜这些链接并检查出来:)
【解决方案3】:

您的生活变得轻松:

private void LoginButton_Click(object sender, System.EventArgs e)
{
    var cmd = "SELECT * FROM bank.user WHERE Name=@name AND Password=@pw";
    
    using var da = new MySqlDataAdapter(cmd, connection);
    da.SelectCommand.Parameters.AddWithValue("@name", NameInput.Text);
    da.SelectCommand.Parameters.AddWithValue("@pw",GetHashString(PasswordInput.Text));

    var dt = new DataTable();
    da.Fill(dt);

    if(dt.Rows.Count == 0)
      WarningLabel.Text = "Wrong Name or Password";
    else
      WarningLabel.Text = $"Welcome {dt.Rows[0]["FullName"]}, your last login was at {dt.Rows[0]["LastLoginDate"]}";

} 

您的生活,变得更轻松(使用 Dapper):

class User{
  public string Name {get;set;} //username e.g. fluffybunny666
  public string FullName {get;set;} //like John Smith
  public string Password {get;set;} //hashed
  public DateTime LastLoginDate {get;set;}
}

//or you could use a record for less finger wear
record User(string Name, string FullName, string Password, DateTime LastLoginDate);

...

  using var c = new MySqlConnection(connection):
  var u = await c.QuerySingleOrDefaultAsync(
    "SELECT * FROM bank.user WHERE Name=@N AND Password=@P", 
    new { N = NameInput.Text, P = GetHashString(PasswordInput.Text)}
  );

  if(u == default)
    WarningLabel.Text = "Wrong Name or Password";
  else
    WarningLabel.Text = $"Welcome {u.FullName}, your last login was at u.LastLoginDate";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2021-11-24
    • 1970-01-01
    相关资源
    最近更新 更多