You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP登录模块异常:封禁用户登录显示登录失败而非封禁提示

问题排查

你的登录系统之所以在账号被封禁时输出登录失败提示,而非你期望的封禁提示,主要是这几个逻辑问题导致的:

  • 冗余且无效的判断:外层已经通过$countLogin == 1确认了账号密码匹配,内部又重复做了一次同样的判断,导致你写在内部else里的封禁提示永远不会被执行。
  • 错误的提示输出方式:当检测到封禁状态($status ==1)时,你用die()输出了纯文本提示,而不是你预设的带样式的alert,而且如果你的status字段值不是1(比如封禁时设置了其他值),这个逻辑直接跳过,反而走到登录成功或失败分支。
  • 重复SQL查询:多次执行查询获取用户信息,不仅低效,还容易出现逻辑漏洞。

修复方案

我重构了你的登录逻辑,调整了判断顺序,优化了SQL查询,确保封禁提示能正确触发,修复后的代码如下:

<?php 
if (!$user->LoggedIn()) { 
    if (isset($_POST['logINBoss'])) { 
        $captcha = htmlspecialchars($_POST["g-recaptcha-response"]); 
        $secret = $odb->query("SELECT `google_secret` FROM `admin` LIMIT 1")->fetchColumn(0); 
        $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); 
        $response = json_decode($response); 

        if (!$captcha || $response->success == false) { 
            echo '<center><div class="alert alert-icon alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>Invalid Captcha Code Entered!</div></center>'; 
        } else { 
            $username = htmlspecialchars($_POST['username']); 
            $password = htmlspecialchars($_POST['password']); 
            $Errors = array(); 

            // 修正用户名长度判断,和提示文本的4-15字符保持一致
            if (!ctype_alnum($username) || strlen($username) < 4 || strlen($username) > 15) { 
                $Errors[] = '<center><div class="alert alert-icon alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>Username Must Be Alphanumeric And 4-15 characters in length</div></center>'; 
            } 
            if (empty($username) || empty($password)) { 
                $Errors[] = '<center><div class="alert alert-icon alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>Fill in all fields</div></center>'; 
            } 

            if (empty($Errors)) { 
                // 一次查询获取用户所有必要信息,避免重复查询
                $SQLGetUser = $odb->prepare("SELECT `ID`, `username`, `password`, `status` FROM `users` WHERE `username` = :username"); 
                $SQLGetUser->execute(array(':username' => $username)); 
                $userInfo = $SQLGetUser->fetch(PDO::FETCH_ASSOC); 

                if ($userInfo) { 
                    // 先验证密码正确性
                    if (SHA1($password) === $userInfo['password']) { 
                        // 再检查账号是否被封禁
                        if ($userInfo['status'] == 1) { 
                            // 获取封禁原因,处理空原因的情况
                            $SQLGetBanReason = $odb->prepare("SELECT `reason` FROM `bans` WHERE `username` = :username"); 
                            $SQLGetBanReason->execute(array(':username' => $username)); 
                            $banReason = $SQLGetBanReason->fetchColumn(0) ?: 'No reason specified';
                            // 输出你期望的带样式的封禁提示
                            echo '<center><div class="alert alert-icon alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>You are banned for Reason: ' . htmlspecialchars($banReason) . '</div></center>'; 
                        } else { 
                            // 账号正常,执行登录流程
                            $logAddr = $odb->prepare("INSERT INTO `loginip` (`username`,`ip`,`date`,`http_agent`) VALUES (:user, :ip, UNIX_TIMESTAMP(NOW()), :agent);"); 
                            $logAddr->execute(array( 
                                ":user" => $username, 
                                ":ip" => $_SERVER['REMOTE_ADDR'], 
                                ":agent" => $_SERVER['HTTP_USER_AGENT']
                            )); 
                            $_SESSION['username'] = $userInfo['username']; 
                            $_SESSION['ID'] = $userInfo['ID']; 
                            echo '<center><div class="alert alert-icon alert-success alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>You have been logged in successfully..</div></center><meta http-equiv="refresh" content="3;url=index.php">'; 
                        } 
                    } else { 
                        // 密码错误,输出登录失败
                        echo '<center><div class="alert alert-icon alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>Login Failed!!</div></center>'; 
                    } 
                } else { 
                    // 用户名不存在,输出登录失败
                    echo '<center><div class="alert alert-icon alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><i class="mdi mdi-check-all"></i>Login Failed!!</div></center>'; 
                } 
            } else { 
                foreach($Errors as $Error) { 
                    echo $Error; 
                } 
            } 
        } 
    } 
} 
?>

修复的核心要点

  • 简化SQL查询:只执行一次查询获取用户的ID、用户名、密码和状态,减少数据库交互次数,提升效率。
  • 调整判断顺序:先确认用户名存在,再验证密码,最后检查封禁状态,逻辑更清晰,避免漏洞。
  • 统一提示样式:移除die(),改用你预设的alert样式输出封禁提示,确保页面样式一致性。
  • 修复细节错误:修正了用户名长度判断的逻辑(原来的<1改为<4),和提示文本的4-15字符要求保持一致。
  • 兼容空封禁原因:如果封禁时未填写原因,默认显示"No reason specified",避免页面出现空白内容。

内容的提问来源于stack exchange,提问作者Immense

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:25:19