好吧,我正在为游戏设置一个简单的登录界面,它使用用户名和密码验证。它连接到数据库检查以查看是否存在用户名和密码,然后查看它是否与数据匹配。如果您插入正确的用户名和密码,它可以正常工作,但如果您执行的操作不在数据库中,则会失败并崩溃。我想知道我这样做了吗?代码如下。
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框。
答案 0 :(得分:4)
ExecuteScalar
正在返回null
。检查您的拼写和数据库。' or 1=1--
(此处插入强制性xkcd链接)答案 1 :(得分: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
将不为null,并且如果bba[1]
为空,则从Text属性调用Equals将导致错误比较。
答案 2 :(得分:0)
由于您在查询中检查用户名和密码,因此如果用户名/ passowrd不正确,则不会有任何结果。
我会选择
var result = command.ExecuteScalar();
my.Close();
if (result !=null )
{
AdminPanel bb = new AdminPanel();
bb.Show();
}
else
{
MessageBox.Show("INCORRECT USER/PASS!");
}
答案 3 :(得分:0)
好吧,如果这是我的项目,我不会使用ExsecuteScalar来获取一个SQL语句的结果,该语句给了我一个以上的单字段返回。您可以使用Exists子句返回“Y”,或使用Count返回一个数字。基本上你只想知道用户记录存在这个用户名和密码。
另外,引用bba [1] .Equals()假设数组的该元素中存在一个实例。如果它为null,则会得到NullRefException。在进行等于检查之前,您应该检查null:
if (bba[1] != null && bba[1].Equals(usernameBox.Text))
答案 4 :(得分:0)
几点意见:
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中选择)和UI访问(读出文本框,弹出对话框) -
你应该努力让问题更加分离,例如:
CheckUserName
,该方法将用户名和密码作为字符串接收,并返回例如bool
但混合用户界面,逻辑和数据访问代码 - 它变得混乱,维护噩梦真的很快!