登录表单正在使用患者表登录。无论我输入正确还是错误的用户名/密码,它总是将我重定向到主页index.aspx,这意味着成功。对于我的下面的代码,我也选择了patientID,因为我想将patientID存储在会话中。
答案 0 :(得分:3)
c#中的整数永远不会为空。它可以是0。
int id = Convert.ToInt32(cmd.ExecuteScalar());
如果没有找到记录,id将为0,因此这个条件
if (id != null)
将始终为true。如果id不是0,则检查
if (id <= 0)
答案 1 :(得分:1)
问题:您需要了解Valu类型永远不会保留null
。因此,检查id对null将始终返回true
,因此您可以在所有条件下登录系统。
解决方案:您应该有一种机制,可以在其中识别ExecuteScalar()
的实际值。如果没有记录,它将返回null
。但是它不会被转换为int为null,所以你应首先检查null为ExecuteScalar()
返回值,然后如果它不为null则将其转换为整数否则分配零。
试试这个:
int id =(cmd.ExecuteScalar()!=null)?Convert.ToInt32(cmd.ExecuteScalar()):0;
if (id > 0)
{
Session.Add("ID", id);
Session.Add("pUsername", txtUserName.Text);
Session.Add("pPassword", txtPassword.Text);
FormsAuthentication.SetAuthCookie(txtUserName.Text, true);
Response.Redirect("index.aspx");
}
编辑:您的系统允许将空用户名和空密码作为有效凭据,因为您在上表中包含空UserName
和Password
的ID为5。因此,为userId 5添加UserName
和Password
,以便它不会允许空用户名和密码。
答案 2 :(得分:1)
免责声明:这不会解决您的问题,但是留下评论并且对您正在做的事情足够重要的时间太长我觉得有理由将其作为答案提供。 < /子>
以下代码确实是真的错误:
cmd.CommandText = "SELECT patientID, pUsername, pPassword FROM patient WHERE pUsername='" + user + "' AND pPassword='" + pwd + "' ";
你必须这样做:
cmd.CommandText = "SELECT patientID, pUsername, pPassword FROM patient WHERE pUsername= @user and pPassword= @password;"
cmd.Parameters.Add("@user", SqlDbType.NVarChar, 16).Value = user;
cmd.Parameters.Add("@password", SqlDbType.NVarChar, 200).Value = pwd;
必须在将用户数据替换为查询的任何位置使用参数。 没有例外。任何其他事情都会导致您的应用被黑客攻击......可能很快就会迟到。
此外,您看起来像是以纯文本格式存储密码。这几乎与不使用参数一样糟糕。存储密码的正确方法是在密码前加上每用户盐,然后存储结果的加密安全散列(bcrypt或scrypt)。在对用户进行身份验证时,您对尝试的密码执行相同的步骤并比较哈希值,而不是直接比较密码。
实际上,您根本不应该编写身份验证代码。身份验证是很容易构建似乎工作的东西之一...传递所有测试...但最终从根本上是以一种微妙的方式存在缺陷导致您发现一年后,你在六个月前被告知。最好的方法是尽可能地使用您所选平台提供的身份验证功能。对于ASP.Net,这意味着学习和使用Membership provider功能。