2015-02-24 113 views
0

我将用户名和密码存储在MySql数据库中。我正在使用以下代码来验证基于来自我的数据库的数据进行登录的凭据。代码工作正常。我的问题是这是否是不好的做法,是否有更好的方法来做到这一点。从数据库检查登录凭证

我的方法是连接到该数据库,提取并将这些信息存储在列表中,并将它们与来自文本框输入的用户输入进行比较。

//Extracting information from the database and storing it in a List 
public void Login() 
{ 
    MySqlCommand cmdReader; 
    MySqlDataReader myReader; 

    userQuery = "SELECT * FROM User"; 
    string name = "Name"; 
    string user = "UserName"; 
    string pw = "Password"; 

    string connString = "server=" + server + "; userid=" + userid + "; password=" + password + "; database=" + database; 
    try 
    { 
     conn.ConnectionString = connString; 
     conn.Open(); 
     cmdReader = new MySqlCommand(userQuery, conn); 
     myReader = cmdReader.ExecuteReader(); 
     while (myReader.Read()) 
     { 
      string tempUser, tempPassword; 
      if (name != null) 
      { 
       tempUser = myReader.GetString(user); 
       tempPassword = myReader.GetString(pw); 
       users.Add(tempUser); 
       passwords.Add(tempPassword); 
      } 
     } 
     myReader.Close(); 

    } 
    catch (Exception err) 
    { 
     MessageBox.Show("Not connected to server. \nTry again later."); 
     Application.Current.Shutdown(); 
    } 
} 

//Comparing the List data with the users input from textbox1 and textbox2 to verify 
private void btn1_Click(object sender, RoutedEventArgs e) 
{ 
    for (int x = 0; x < users.Count; x++) 
    { 
     for (int y = 0; y < passwords.Count; y++) 
     { 
      if (users[x] == textbox1.Text && passwords[y] == textbox2.Text) 
      { 
       MessageBox.Show("Login successful"); 
      } 
     } 
    } 
} 
+0

该代码如何正常工作?用户没有与密码关联?你有他们在两个单独的集合。 – Paparazzi 2015-02-24 20:27:49

+0

我有他们在2个独立的集合,但检查时,使用嵌套循环检查他们相同的时间相同的索引。经过测试,它的工作原理。 – kar 2015-02-24 20:38:03

+0

你有两个列表上的嵌套循环,并比较索引?确定它的工作原理,但这远非最佳。 – Paparazzi 2015-02-24 20:41:42

回答

5
  1. 不要储存密码在数据库中纯文本,存储他们的哈希值。请参阅(Best way to store password in database
  2. 而不是查询和检索所有用户,发送特定的user namepassword到数据库并比较返回的结果。

作为一个侧面说明,不要使用字符串连接成SQL查询,而是使用参数,像:

using (MySqlCommand cmd = new MySqlCommand("SELECT Count(*) FROM User = @userName AND password = @password"),conn) 
{ 
    cmd.Parameters.AddwithValue("@username", username); 
    cmd.Parameters.AddwithValue("@password", password); 
    .... 
    var count = cmd.ExecuteScalar(); //and check the returned value 
} 

目前您从User表中检索所有记录,然后将其与比较客户端的价值观,想象一下,如果你有大量的用户,那么为客户端提供大量数据是没有意义的。

+0

指针2:澄清,你的意思不是从数据库中提取信息并存储到列表中,而是从文本框1和2输入中收集到的信息并使用它们查询数据库? – kar 2015-02-24 20:30:05

+0

@keshk,是的,想象一下,如果你有数百万用户,那么你会怎么做呢? – Habib 2015-02-24 20:30:34

+0

我喜欢你的答案,但如果我有数以百万计的使用,那么我实际上更可能将这些信息存储在列表中以防止SQL关闭流量。 – Paparazzi 2015-02-24 20:33:40

0

我会为此使用存储过程,然后发送用户名和密码作为参数。根据这是Intranet应用程序,还是互联网上的某些内容,我可能会按照Habib所建议的那样进行散列操作。

1

在两个列表上循环并比较索引不是最优的。
如果你想预先获取一个字典。
在字典键查找是O(1)

Dictionary<string,string> UserIDpw = new Dictionary<string,string>(); 
while (myReader.Read()) 
{ 
    UserIDpw.Add(myReader.GetString(0), myReader.GetString(1)); 
} 

但是从哈比卜答案是一个更好的办法。您没有性能问题需要您预取并预取带有问题。对于一个你在网络服务器上有密码的地方,你更容易破解。