Сбои программы после проверки базы данных на пароль C # - PullRequest
2 голосов
/ 03 марта 2011

Ну, я работаю над простым экраном входа в игру, и он использует аутентификацию по имени пользователя и паролю.Он подключается к базе данных, проверяет наличие имени пользователя и пароля, а затем проверяет, соответствуют ли они данным.Если вы введете правильное имя пользователя и пароль, он будет работать нормально, но если вы сделаете тот, которого нет в базе данных, это приведет к сбою и сбоям.Мне было интересно, я делаю это правильно?код ниже.

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 ]

4 голосов
/ 03 марта 2011
  1. вы возвращаете две вещи из вашего запроса, а не одну.
  2. ExecuteScalar возвращается null. Проверьте правильность написания и базу данных.
  3. Хранение паролей в виде открытого текста в вашей базе данных ... по крайней мере, дурной тон.
  4. молись, чтобы ты никогда не встречал мистера. ' or 1=1-- (вставить обязательную ссылку xkcd здесь)
2 голосов
/ 03 марта 2011

Во-первых: Об атаках впрыска Sql

Вы должны заключить логику в блок 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]При попытке использовать метод Equals будет выдано исключение нулевой ссылки.Переключая их, usernameBox.Text не будет нулевым, а вызов Equals из свойства Text просто приведет к ложному сравнению, если bba[1] равно нулю.

0 голосов
/ 03 марта 2011

Пара комментариев:

  • не объединяйте свои запросы SQL - используйте параметризованные запросы, чтобы избежать внедрения SQL
  • вы должны поместить свои SqlConnection и SqlCommand в 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) и доступ к пользовательскому интерфейсу (считывает текстовые поля, открывают диалоговые окна) в одном и том же фрагменте кода -

Вы должны стремиться к большему разделению интересов, например,

  • определить метод CheckUserName, который принимает имя пользователя и пароль в виде строки и возвращает, например, bool
  • из вашего обработчика событий, получить информацию из пользовательского интерфейса (прочитать текстовые поля), вызвать эту отдельную функцию с этими значениями, а затем обработать возвращенное значение

Но смешивать пользовательский интерфейс, логику и код доступа к данным - это очень грязно и очень быстро требует обслуживания!

0 голосов
/ 03 марта 2011

Ну, если бы это был мой проект, я бы не использовал ExsecuteScalar для получения результата оператора SQL, который дал мне больше, чем возвращение в одно поле.Вы можете использовать предложение Exists для возврата «Y» или Count для возврата числа.По сути, все, что вам нужно, это знать, что существует запись пользователя с этим именем пользователя и паролем.

Кроме того, ссылка на bba [1] .Equals () предполагает, что экземпляр существует в этом элементе массива.Если это нуль, вы получаете исключение NullRefException.Вы должны проверить на нулевое значение перед выполнением проверки на равенство:

if (bba[1] != null && bba[1].Equals(usernameBox.Text))
0 голосов
/ 03 марта 2011

Поскольку вы проверяете имя пользователя и пароль в своем запросе, вы не получите никаких результатов в случае неверного имени пользователя / пароля.

Я бы просто пошел с

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


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

            }
...