wpf 从数据库检查登录凭据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28705515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:58:51  来源:igfitidea点击:

Check login credentials from a database

c#mysqlwpf

提问by kar

I am storing usernames and passwords in a MySql database. I am using the following code to verify the credentials based on the data from my database for a login. The codes works fine. My question is whether this is bad practice and is there a better way to do this.

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

My approach is to connect to that database, extract and store those information in a List and compare them to the users input coming from a text box input.

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

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

回答by Habib

  1. Do not store password in plain text in database, store their hashes. See(Best way to store password in database)
  2. Instead of querying and retrieving all the users, send specific user nameand passwordto database and compare the returned result.
  1. 不要将密码以纯文本形式存储在数据库中,而是存储它们的哈希值。请参阅(在数据库中存储密码的最佳方法
  2. 不是查询和检索所有用户,而是将特定的user name和发送password到数据库并比较返回的结果。

As a side note, do not use string concatenation to form SQL queries, instead use parameters, something like:

作为旁注,不要使用字符串连接来形成 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
}

Currently you are retrieving all records from Usertable and then comparing it with the values at client side, imagine if you have a large number of users, brining that much data to client end would not make sense.

目前,您正在从User表中检索所有记录,然后将其与客户端的值进行比较,想象一下,如果您有大量用户,将那么多数据带到客户端是没有意义的。

回答by paparazzo

Looping on two list and comparing index is not a optimal.
If you want to pre fetch then a Dictionary.
Key lookup on Dictionary is O(1)

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

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

But the answer from Habib is a better approach. You don't have a performance issue the requires you to prefetch and prefetch comes with issues. For one you have the passwords on the web server where thy are easier to hack.

但是 Habib 的答案是更好的方法。您没有需要预取和预取的性能问题。一方面,您在网络服务器上拥有密码,在那里您更容易破解。

回答by David P

I would use a stored procedure for this, and then send username and password as parameters. Depending on whether this is intranet app, or something that is out on the internet, I might do the hash thing as Habib suggests.

我会为此使用存储过程,然后将用户名和密码作为参数发送。根据这是 Intranet 应用程序还是 Internet 上的某些内容,我可能会按照 Habib 的建议进行哈希处理。