C# 具有两个访问级别的登录系统
我正在尝试创建一个具有两个访问级别的登录系统。如果访问级别为1,则接收“护理者主页”,如果访问级别为2,则接收“管理员页面”。登录表单有一个变量,该变量根据数据库中的凭据验证用户名和密码,当用户单击按钮且tryLogin变量返回true时,访问级别取自数据库中用户名与用户名文本字段匹配的数据库 将显示消息“无效登录凭据”,而不是加载任何表单。我花了很长时间在这方面,我迷路了,我希望这足以解释这个问题C# 具有两个访问级别的登录系统,c#,C#,我正在尝试创建一个具有两个访问级别的登录系统。如果访问级别为1,则接收“护理者主页”,如果访问级别为2,则接收“管理员页面”。登录表单有一个变量,该变量根据数据库中的凭据验证用户名和密码,当用户单击按钮且tryLogin变量返回true时,访问级别取自数据库中用户名与用户名文本字段匹配的数据库 将显示消息“无效登录凭据”,而不是加载任何表单。我花了很长时间在这方面,我迷路了,我希望这足以解释这个问题 public bool tryLogin(string uname, string pword)
public bool tryLogin(string uname, string pword)
{
MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";");
MySqlCommand cmd = new MySqlCommand("SELECT * FROM Staff WHERE username = '" + uname + "' AND password ='" + pword + "';");
cmd.Connection = con;
con.Open();
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.Read() != false)
{
if (reader.IsDBNull(0) == true)
{
cmd.Connection.Close();
reader.Dispose();
cmd.Dispose();
return false;
}
else
{
cmd.Connection.Close();
reader.Dispose();
cmd.Dispose();
return true;
}
}
else
{
return false;
}
}
private void LoginBT_Click(object sender, EventArgs e)
{
if (tryLogin(uname.Text, pword.Text) == true)
{
MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";");
MySqlCommand cmd2 = new MySqlCommand("SELECT access_level FROM Staff WHERE username = '" + uname + "';");
cmd2.Connection = con;
con.Open();
MySqlDataReader reader = cmd2.ExecuteReader();
if (cmd2.Equals("1"))
{
this.Hide();
CarerHomePage CarerHomePage = new CarerHomePage();
CarerHomePage.Show();
}
if (cmd2.Equals("2"))
{
this.Hide();
AdministratorHome AdministratorHome = new AdministratorHome();
AdministratorHome.Show();
}
else
{
MessageBox.Show("Invalid Login Credentials");
}
}
}
}
}
您需要阅读有关SQL注入的内容。尝试添加文本 '或1=1-- 进入用户名文本框并尝试登录。你也应该考虑阅读内置的ASP.NET用户管理/角色-这是角色位,这将为你提供很好的服务。 来自ScottGu的好链接:
您的问题似乎是将
cmd2
(ExecuteReader
的实例)与字符串进行比较。为什么这是真的?您应该将查询结果检查为字符串,而不是查询命令
此外,即使已加载CarrerHomePage,if语句也会显示消息框。你应该这样做:
if (cmd2.Equals("1"))
{
this.Hide();
CarerHomePage CarerHomePage = new CarerHomePage();
CarerHomePage.Show();
}
else if (cmd2.Equals("2"))
{
this.Hide();
AdministratorHome AdministratorHome = new AdministratorHome();
AdministratorHome.Show();
}
else
{
MessageBox.Show("Invalid Login Credentials");
}
是的,这里有很多问题。您应该始终使用参数化查询
问题是您使用cmd.Equals而不是使用DataReader来检索结果行
如果只想检索单个值,可以使用ExecuteScalar。我建议彻底阅读MySqlCommand上的文档
最后,您可以使用块将对象包装在中。。。这将自动关闭并处置您的选项。缩短代码
public bool tryLogin(string uname, string pword)
{
using(MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";"))
using(MySqlCommand cmd = new MySqlCommand("SELECT * FROM Staff WHERE username = @name AND password = @pwd;"))
{
cmd.Parameters.AddWithValue("@name", uname);
cmd.Parameters.AddWithValue("@pwd", pword);
cmd.Connection = con;
cmd.Connection.Open();
using(var reader = cmd.ExecuteReader())
{
return reader.Read() && !reader.IsDBNull(0));
}
}
}
private void LoginBT_Click(object sender, EventArgs e)
{
if (tryLogin(uname.Text, pword.Text))
{
using(MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";"))
using(MySqlCommand cmd2 = new MySqlCommand("SELECT access_level FROM Staff WHERE username = '" + uname + "';"))
{
cmd2.Connection = con;
cmd2.Connection.Open();
using(MySqlDataReader reader = cmd2.ExecuteReader())
{
if(reader.Read())
{
var accessLevel = reader.GetInt32("access_level");
switch(accessLevel)
{
case 1:
this.Hide();
CarerHomePage CarerHomePage = new CarerHomePage();
CarerHomePage.Show();
break;
case 2:
this.Hide();
AdministratorHome AdministratorHome = new AdministratorHome();
AdministratorHome.Show();
break;
default:
MessageBox.Show("Invalid Login Credentials");
break;
}
}
}
}
}
}
虽然还有很大的改进空间,但我们只考虑明显错误的地方。
让您忙的问题是,您正在将SQL命令的执行结果与命令本身进行比较:
MySqlDataReader reader = cmd2.ExecuteReader();
if (cmd2.Equals("1")) // What the fail?
我想你的意思是:
object accessCode = cmd2.ExecuteScalar();
if (accessCode != null && accessCode != DBNull.Value)
{
if (accessCode.ToString() == "1")
{
this.Hide();
CarerHomePage CarerHomePage = new CarerHomePage();
CarerHomePage.Show();
}
好的,如果凭据错误,我可以确认try-login-bool工作正常
消息框显示。但是,如果我的凭据正确,则无论我在access\u级别中放置了什么,都不会加载任何表单。它进展缓慢,我正在学习一些关于使用调试器的教程,因为我对调试器还是很陌生的
私有无效登录单击(对象发送者,事件参数e)
{
if (tryLogin(uname.Text, pword.Text) == true)
{
using (MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";"))
using (MySqlCommand cmd2 = new MySqlCommand("SELECT access_level FROM Staff WHERE username = '" + uname + "';"))
{
cmd2.Connection = con;
con.Open();
object access_level = cmd2.ExecuteScalar();
if (access_level != null && access_level != DBNull.Value)
{
if (access_level.ToString() == "1")
{
this.Dispose();
CarerHomePage CarerHomePage = new CarerHomePage();
CarerHomePage.Show();
}
else if (access_level.ToString() == "2")
{
this.Dispose();
AdministratorHome AdministratorHome = new AdministratorHome();
AdministratorHome.Show();
}
}
}
}
else
{
MessageBox.Show("Invalid Login Credentials");
}
}
}
}啊,我的眼睛!漏洞很多。你没听说过吗?“我花了很长时间研究这个”告诉我你可能没有使用调试器。你是在没有VisualStudio的帮助下写这篇文章的吗?如果是这样的话,你可能会考虑使用,直到你觉得用C语言编程更舒服。虽然你的观点比我想的要好得多,所以你阻止了我看起来也很愚蠢好点,但不直接解决这个问题,唉,这里没有+1,但评论说这绝对重要和必要的考虑。Chris-我不同意-在一开始加入任意的“两级登录”系统会削弱系统,以便在有人要求时进一步扩展,例如,可以访问某些管理功能的护理人员用户。从一开始,基于角色的授权是一种更好的方式。在这里,我绝对同意Paddy的观点。在你真正了解自己在做什么之前,我认为最好使用一个经过验证的安全框架,而不是拼凑自己的框架。@Joel:我从来都不确定积分奖励。对于一个好的答案是否应该回答实际的问题,或者说“你问错了问题”是否也是一个好的答案,有什么有用的指导方针吗?我是从前者的角度来考虑的,而这个答案更像是后者。