2011-03-02 21 views
2

嗯,我正在爲一個遊戲的簡單登錄屏幕,它使用用戶名和密碼認證。它連接到數據庫檢查以查看用戶名和密碼是否存在,然後查看它是否與數據匹配。如果你插入正確的用戶名和密碼,它可以正常工作,但如果你做了一個不在數據庫中的失敗並崩潰。我想知道我做對了嗎?代碼如下。如果插入錯誤的程序檢查數據庫密碼C後崩潰#

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

的不正確的用戶名/密碼箱從不顯露。

+3

你真的*真的* **真的**需要查看SQL注入。 – 2011-03-02 21:38:38

回答

0

夫婦的評論:

  • 沒有串起來你的SQL查詢 - 使用參數化查詢避免SQL注入
  • 你應該把你的SqlConnectionSqlCommand分成using(....) { ... }
  • 如果你返回兩個值,你不應該使用.ExecuteScalar() - 那個ca LL只適用於單列,單柱回報

因此,所有的一切,你的代碼應該是這樣的:

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的信息(讀出文本框),調用這些值是獨立的功能,然後處理返回的值

但混合UI,邏輯和數據訪問代碼 - 它變得非常混亂,而且很快就會出現維護噩夢!

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將不爲空,呼叫從文本屬性等於只會導致錯誤的比較,如果bba[1]爲null。

4
  1. 你是從你的查詢,而不是一個返回兩件事情。
  2. ExecuteScalar正在返回null。檢查拼寫和數據庫。
  3. 保持數據庫中的明文密碼至少是不好的味道。
  4. 祈求你永遠不會遇見先生。 ' or 1=1--(此處插入強制性XKCD鏈接)
0

由於要檢查查詢中的用戶名和密碼,你不會有不正確的用戶名/ passowrd的情況下,任何結果。

我只想去與

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


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

      } 
0

好吧,如果這是我的項目,我不會使用ExsecuteScalar獲得這給了我比單場回報更多的是SQL語句的結果。您可以使用Exists子句返回「Y」,或使用Count返回一個數字。基本上所有你想要的是知道用戶記錄與該用戶名和密碼存在。

另外,BBA引用[1] .Equals()假定一個實例在該陣列的該元素的存在。如果它爲空,你會得到NullRefException。做一個之前,您應該檢查空等於檢查:

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