更正之前《登录小案例》密码错3次15分钟内不准登录
之前写的一篇 数据库查询的一般写法:从登陆验证小案例中得到的一些启示和经验。是有点问题的。
问题在于判断15分钟内密码错误的代码。
原代码如下:
//使用using对SqlDataReader进行资源管理 using (SqlDataReader dr = cmd.ExecuteReader()) { if (dr.HasRows) { dr.Read(); if (dr.GetInt32(5) > 15) { //重置uErrTimes SqlHelper.ResetErrTimes(dr.GetInt32(0)); } //加上这句话,可以解决结果集不同步的情况 //判断次数只能在时间小于15分钟的情况下才能进行 if (dr.GetInt32(5) <= 15) { if (dr.GetInt32(3) >= 3) { MessageBox.Show("密码错误已三次,请在15分钟后登陆!"); return; } } if (String.Equals(dr.GetString(2), txtPassWord.Text.Trim())) { MessageBox.Show("登陆成功!"); } else { MessageBox.Show("密码错误,登陆失败"); //更新错误次数 SqlHelper.UpdateErrTimes(dr.GetInt32(0)); //记录错误时间 SqlHelper.RecordErrTime(dr.GetInt32(0)); } } else { MessageBox.Show("不存在此账户!"); return; } }
其中
if (dr.GetInt32(5) > 15) { //重置uErrTimes SqlHelper.ResetErrTimes(dr.GetInt32(0)); } //加上这句话,可以解决结果集不同步的情况 if (dr.GetInt32(3) >= 3) { MessageBox.Show("密码错误已三次,请在15分钟后登陆!"); return; }
首先判断距离上一次登录是不是超过了15分钟,如果超过了15分钟,则执行重置错误次数(ErrTimes)的代码。但是这个有一个问题:
假设你现在已经密码错误3次了,然后过了15分钟,你再来登录。按道理说应该没问题了。但是当你15分钟后第一次登录,dr中取到的次数是3,即使进入了if (dr.GetInt32(5) > 15)这个语句,更新了错误次数,下面所使用的错误次数依然还是更新之前的。因此密码输错三次后的15分钟后的第一次登录照样显示“登录锁定”。
解决办法有两个:
1.重置错误次数之后理解跟新dr对象在服务器中的查询结果集。即:
if (dr.GetInt32(5)>15) { SqlHelper.ResetErrTimes(dr.GetInt32(0)); } //更新之前必须关闭 dr.Close(); //重新加载 dr = cmd.ExecuteReader();
2.将判断时间大于15分钟和判断次数的代码写成嵌套
if (dr.GetInt32(5) < 15) { if (dr.GetInt32(3) >= 3) { MessageBox.Show("登录锁定,15分钟后重试!"); return; } } else { //更新错误次数 SqlHelper.UpdateErrTimes(dr.GetInt32(0)); }
一般只有在登录时间少于15分钟的情况下,才会判断密码次数。超过15分钟就直接更新次数为0,而不用再判断登录次数了。
这个跟业务逻辑紧密结合,建议这样写!