PHP实现登录错误次数限制
以下代码旨在实现逻辑,状态记录在cookie里不好,攻击者可以清除cookie,为了安全起见应将状态存储到缓存服务器,如redis
<div style="width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;">
<form method="post" action='login.php?login=true'>
<div>账号<input type="text" name="username" value="errorAccount"/></div>
<div>密码<input type="password" name="password" value="errorAccount"/></div>
<button>登录</button>
</form>
<div>
<?php
session_start();
$login = empty($_GET['login']) ? '' : trim($_GET['login']);
$username = empty($_POST['username']) ? '' : trim($_POST['username']);
$password = empty($_POST['password']) ? '' : trim($_POST['password']);
if ($login == 'true') {
login();
}
function login() {
global $username;
global $password;
$limitErrorTimeRange = 1; // 错误累计时间范围,分钟,在这个范围内超过规定次数则锁定一段时间才可登录
$limitErrorCount = 5; // 限制连续登录错误次数,时间范围内连续错误满此次数后锁定一段时间才可登录
$lockTime = 2; // 超限后锁定时长,分钟
$userLoginState = array();
// 初始化用户登录情况全局变量
if (!isset($_SESSION['USER_LOGIN_ERROR_STATE'])) {
$_SESSION['USER_LOGIN_ERROR_STATE'] = array(
// 用username作为key,存当前用户的状态信息
$username => array(
'prevLoginErrorTime' => 0, // 上次登录错误时间戳(秒)
'errorCount' => 0 // 时间范围内累计错误次数
)
);
}
// 得到当前用户的状态信息
$userLoginState = $_SESSION['USER_LOGIN_ERROR_STATE'][$username];
// print_r($userLoginState);
// echo '<br/>';
$userPrevLoginErrorTime = $userLoginState['prevLoginErrorTime'];
$userErrorCount = $userLoginState['errorCount'];
$loginCheck = true;
// 若上次错误次数超限则进行解除判定
if ($userErrorCount >= $limitErrorCount) {
// 还未到解禁时间,返回限制倒计时提示
// 计算锁定剩余分钟数
$lockSurplusMinutes = ceil((($userPrevLoginErrorTime + $lockTime * 60 - time()) / 60));
if ($lockSurplusMinutes > 0) {
echo '你因登录失败次数过多已被锁定,请于' . $lockSurplusMinutes . '分钟后再登录!';
return; // 必须return,防止下面代码修改信息
}
// 若已超锁定时长则允许重新登录(重新计数)
else {
$userErrorCount = 0;
// 登录验证
if ($username != 'user' && $password != '123') {
$loginCheck = false;
echo '1 登录失败<br/>';
} else {
echo '1 登录成功<br/>';
}
}
}
// 未超过错误次数限制
else {
// 若上次登录已超过累计时间范围则允许登录并重新开启一轮累计
if (time() - $userPrevLoginErrorTime > $limitErrorTimeRange * 60) {
$userErrorCount = 0;
}
// 登录验证
if ($username != 'user' && $password != '123') {
$loginCheck = false;
echo '登录失败<br/>';
} else {
echo '登录成功<br/>';
}
}
if (!$loginCheck) {
// 验证不通过,错误次数+1
$userErrorCount = $userErrorCount + 1;
} else {
// 验证通过,重置错误次数
$userErrorCount = 0;
}
echo $userErrorCount . '<br/>';
// 更新用户登录错误信息
$_SESSION['USER_LOGIN_ERROR_STATE'][$username]['prevLoginErrorTime'] = time(); // 秒
$_SESSION['USER_LOGIN_ERROR_STATE'][$username]['errorCount'] = $userErrorCount;
// echo '<br/>';
// print_r($_SESSION['USER_LOGIN_ERROR_STATE']);
// echo 'ahah<br>';
}
?>
</div>
</div>

浙公网安备 33010602011771号