PHP实现3次登录失败跳转注册功能时尝试次数不计数问题求解
问题诊断
- 状态丢失:登录失败后执行
window.location = "index.php"属于GET跳转,本次累加后的尝试次数没有传递到新页面,新页面会重新初始化$atmp = 0,隐藏域值每次都会重置,导致计数无法累加。 - 逻辑错误:
if($query)判断无意义,$query是自定义的SQL字符串,永远为真,应该判断查询执行结果$result。 - 安全问题:直接拼接用户输入到SQL语句存在SQL注入漏洞;用前端隐藏域存储尝试次数,用户可通过修改前端代码绕过限制。
修复方案
采用服务端session存储登录尝试次数,既不会因页面跳转丢失状态,也无法被用户篡改。
修复后PHP代码
<?php session_start(); // 初始化登录尝试次数 if (!isset($_SESSION['login_attempt'])) { $_SESSION['login_attempt'] = 0; } $atmp = $_SESSION['login_attempt']; if (isset($_POST['login'])) { // 次数达上限直接跳转注册页 if ($atmp >= 3) { echo '<script> alert("登录错误次数已达上限,请先注册");window.location = "accountregistration.php";</script>'; exit; } $user = trim($_POST['username']); $pword = trim($_POST['password']); include ("connection.php"); // 预处理SQL避免注入 $stmt = mysqli_prepare($conn, "SELECT fld_username, fld_password FROM tbl_account WHERE fld_username = ? AND fld_password = ?"); mysqli_stmt_bind_param($stmt, "ss", $user, $pword); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($result) > 0) { // 登录成功清空尝试次数 $_SESSION['login_attempt'] = 0; echo "<script> alert('登录成功!'); window.location = 'profile.php'; </script>"; exit; } else { // 登录失败次数累加 $_SESSION['login_attempt']++; $atmp = $_SESSION['login_attempt']; if ($atmp >= 3) { echo '<script> alert("登录错误次数已达3次,请注册账号");window.location = "accountregistration.php";</script>'; exit; } echo '<script> alert("用户名或密码错误,当前已尝试'.$atmp.'次");</script>'; } } ?>
调整后HTML代码
删除冗余的隐藏域即可
<!DOCTYPE html> <html> <head> <title>LOGIN</title> </head> <body> <form action="" method="POST"> <fieldset> <legend>Login</legend> <label>Username:</label><input type="Text" name="username" id="username" required><br><br> <label>Password:</label><input type="password" name="password" id="password" required><br><br>                <input name="login" type="submit" value="Login">   <input name="clear" type="reset" value="Clear"> </fieldset> </form> </body> </html>
内容的提问来源于stack exchange,提问作者user17333424
相关产品推荐
相关产品推荐

