我怎样才能防止这些获得SQL注入的代码呢? 这是我正在学习的登录系统。 这是密码!
if (!(string.IsNullOrWhiteSpace(textBox1.Text)) && !(string.IsNullOrWhiteSpace(textBox2.Text)))
{
MySqlConnection mcon = new MySqlConnection("datasource = 127.0.0.1; port = 3306; username = root; password = ; database = rpgmaster;");
mcon.Open();
DataTable table = new DataTable();
MySqlDataAdapter adapter = new MySqlDataAdapter("Select * From users where Username = '" + textBox2.Text + "' and password = '" + textBox1.Text + "'", mcon);
adapter.Fill(table);
if (table.Rows.Count <= 0)
{
MessageBox.Show("Você não está registrado!");
}
else
{
MessageBox.Show("Logado com sucesso! ");
}
mcon.Close();
}
谢谢你的帮助! 真的很感激!
请尝试使用参数,请参阅下面更新的代码示例:
if (!(string.IsNullOrWhiteSpace(textBox1.Text)) && !(string.IsNullOrWhiteSpace(textBox2.Text)))
{
using (MySqlConnection mcon = new MySqlConnection("datasource = 127.0.0.1; port = 3306; username = root; password = ; database = rpgmaster;"))
{
mcon.Open();
MySqlCommand cmd = new MySqlCommand("Select * from users where username=?username and password=?password", mcon);
cmd.Parameters.Add(new MySqlParameter("username", textBox2.Text));
cmd.Parameters.Add(new MySqlParameter("password", textBox1.Text));
MySqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows == true)
{
MessageBox.Show("Você não está registrado!");
}
else
{
MessageBox.Show("Logado com sucesso! ");
}
}
}
如果您正在学习,您也许可以从这种旧的低级的数据访问方式转向使用一些更现代,更简单的方式。 Dapper就是一个库的例子,它并不比你已经知道的东西有很大的飞跃,但却能让你的生活更美好:
using(var conn = new MySqlConnection("conn str here"){
var sql = "SELECT count(*) FROM tblUsers WHERE username = @u AND password = @p";
var prm = new {
u = txtUsername.Text, //give your textboxes better names than textbox2,textbox1!
p = txtPassword.Text.GetHashCode() //do NOT store plain text passwords!
};
bool valid = await conn.QuerySingleAsync<int>(sql, prm) > 0;
if(valid)
... valid login code
else
... invalid login
}
关于这一点的一些注意事项:
u=“My UserName”
QuerySingleAsync
查询类型为it的单个值,如果该值大于0,则登录有效Dapper让事情变得更好的地方是它能够将对象转换为查询,反之亦然; 这只是一个基本的计数示例,但假设您有一个user类:
class User
{
string Name { get; set; }
string HashedPassword { get; set; }
int age {get; set; }
}
并且您有一个类似的表tblUsers(列名与属性名类似),那么您可以进行如下查询:
User u = new User() { Name = "someuser" };
User t = await conn.QuerySingleAsync<User>("SELECT Name, HashedPassword, Age FROM tblUsers WHERE Name = @Name", u);
我们想从某个用户那里查找所有的信息,所以我们用这个名称集创建一个新用户(我们也可以使用匿名类型),而不使用其他任何东西,并将其作为参数参数传递。 Dapper将看到包含@Name的查询,从我们传入的用户u中提取名称的内容,并运行查询,从响应中提取所有数据,为我们创建一个新用户,并填充其所有属性。 要用这种老方法,我们必须:
写那些代码是重复的,而且真的很枯燥。 在计算中,当我们有一些重复和枯燥的事情,我们一生中需要做成千上万次(比如序列化到json,调用webservice,设计windows UI)时,我们会找到一些方法让计算机去做那些重复和枯燥的事情; 他们比我们做得更快更准确。 这正是Dapper所做的; 它消除了这种枯燥的重复,并将其简化为一行,在一行中您可以说出您想要返回的内容,使用什么查询,使用什么参数。 并且它保持您的UI工作:
await x.QueryAsync<type>(query, parameters)
赢了。 寻找一些时髦的教程!
使用参数
using (MySqlConnection mcon = new MySqlConnection(connectionString))
{
string commandText = "SELECT * FROM users WHERE Username = '@tbxText'"
SqlCommand command = new SqlCommand(commandText, mcon);
command.Parameters.AddWithValue("@tbxText", textBox2.Text);
}