一、基本思路
(1)需要在数据库中记录某个用户的登陆失败次数
(2)需要在数据库中记录最后一次登陆的时间,用于判断是否接触限制
(3)每一次登陆时,都需要从数据库中取出这两个值,从而进行判断
二、技术准备
1、核心sql语句操作
同时更新两个字段并设置时间为现在:update user set failcount = failcount+1, lasttime=now where id = ?
比较两个时间的差值,单位可以是分或者秒等:select lasttime, now(),TIMESTAMPDIFF(MINUTE,lastimenow()) from user;
2、在php中处理时间
// PHP设置默认时区为中国:
date_default_timeone_set("PRC")
// PHP生成年月日时分秒:
echo date('Y-m-d' H:i:s);
PHP比较两个时间的差值
$time1
$time2
echo strtotime($time2)-strtotime($time1)
PHP代码实现
$sql = "SELECT id,username,`password`,failcount ,TIMESTAMPDIFF(MINUTE,lasttime,now()) FROM user where username =?";
// $result = $conn -> query($sql) or die("SQL语句执行失败");
$stmt = $conn->prepare($sql);
$stmt->bind_param('i',$username); //绑定查询参数
$stmt->bind_result($id,$username2,$password2,$failcount,$timediff); //绑定结果参数
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows() == 1){
$row = $stmt->fetch();
if($failcount >5 && $timediff < 60){
die("user-locked");
}
if($password == $password2){
$sql = "update user set failcount=0 where id=?";
$stmt=$conn->prepare($sql);
$stmt->bind_param("i",$id);
$stmt->execute();
echo "login-pass";
# 登陆成功后,记录session变量
$_SESSION['username'] = $username;
$_SESSION['islogin'] = 'true';
echo "<script>location.href='./welcome.php'</script>";
}
else{
$sql = "update user set failcount=failcount+1,lasttime=now() where id=?";
$stmt=$conn->prepare($sql);
$stmt->bind_param("i",$id);
$stmt->execute();
// echo "pass-error"; // 不建议直接明确告诉用户,是密码还是用户名错误
echo "login-fail";
echo "<script>location.href='./login.html'</script>";
}
登陆模块的各类防护措施:
验证码:
不建议使用图片验证码
登陆次数限制
,并记录IP
多因素认证:
账密+短信
记录用户常用的IP地址区域
,如果在不常用区域登陆,预警
除了使用session,还可以使用token