ГДЕ Name='{NameInput.Text}' AND Password='{GetHashString(PasswordInput.Text)} не работает

avatar
Nebula.EXE
9 августа 2021 в 06:50
90
3
1

Я пытаюсь заставить свою 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

Источник
HoneyBadger
9 августа 2021 в 06:53
1

Почему вы ожидаете исключения, если записи не выбраны?

Gabriel Heming
9 августа 2021 в 06:54
0

Запрос Select не генерирует ошибку. Вы должны проверить, были ли возвращены записи.

Nebula.EXE
9 августа 2021 в 06:55
0

что вы имеете в виду, говоря, что записи не выбраны?

mjwills
9 августа 2021 в 07:15
1

Остановитесь прямо сейчас и прочитайте coderhelper.com/questions/14376473/… .

Ответы (3)

avatar
Cleptus
9 августа 2021 в 07:00
1

ExecuteNonQuery не предназначен для использования с инструкциями SQL, которые возвращают данные, вы должны использовать ExecuteReader или ExecuteScalar, вы можете проверить документацию MySqlCommand.ExecuteReader<73564883545614><

Предупреждение. В вашем коде есть уязвимость SQL Injection в этой части инструкции SQL Name='{NameInput.Text}' Проверьте это объяснение SQL Injection<7356489>354

Пример использования (из документации, слегка измененный):

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

Nebula.EXE
9 августа 2021 в 07:07
0

Спасибо, это помогло, и все дорожат этими ссылками и проверяют их :)

avatar
Caius Jard
9 августа 2021 в 11:08
0

Ваша жизнь стала проще:

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";
avatar
the_coding_cat
9 августа 2021 в 06:59
0

Вы должны проверить, есть ли возвращенные записи. 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

Cleptus
9 августа 2021 в 07:04
0

Справедливости ради, только имя будет уязвимо для SQL-инъекций, а столбец «Пароль» — нет, потому что не будет использоваться прямой ввод (обратите внимание на вызов функции GetHashString).

the_coding_cat
9 августа 2021 в 07:17
0

@Cleptus Oww Да, это то, что я имел в виду, спасибо, что заметили.