【发布时间】:2014-03-28 08:46:36
【问题描述】:
我正在使用蛮力检查器构建登录脚本,当触发时,它会显示 reCAPTCHA。我遇到的问题是,当输入正确的用户名/密码/验证码响应时,登录脚本会运行,但直到大部分页面内容已加载(这发生在提交表单后)。结果是我必须按 F5 来刷新页面并重新提交表单数据,以便在页面开始加载时会话处于活动状态。
现在,我遇到的问题是,一旦提交表单(当它需要验证码时),直到 index.php 到达会话才会开始
else {
$captchaResponse = 1;
$auth = Auth::verifyPass($userName,$password,$captchaResponse);
}
我不知道如何重新组织它,以便在此之前开始会话。有什么想法吗?
-
第一部分是 index.php 页面,其中包含在检测到暴力尝试时触发的代码。这部分代码以条件 if($auth === "bruteForce") 开头 此代码显示 reCAPTCHA 并应该将用户名、密码和 reCAPTCHA 响应代码(0-错误响应,1-正确响应)提交回登录功能。
<?php include('includes/header.php'); spl_autoload_register(function ($class){ include 'includes/class.' . $class . '.php'; }); if(null !==(filter_input(INPUT_POST,'userName'))){$userName = filter_input(INPUT_POST,'userName');} if(null !==(filter_input(INPUT_POST,'password'))){$password = filter_input(INPUT_POST,'password');} if(isset($userName)&& isset($password)){ $auth = Auth::verifyPass($userName,$password); } if(isset($_GET['logout']) && $_GET['logout'] == true){ session_start(); session_destroy(); setcookie ("PHPSESSID", "", time() - 3600, "/"); header("Location: index.php"); } if(Auth::checkLoggedIn() === true){ if(session_id() !== ''){echo 'Session ID is not blank<br />';} echo '<a href="index.php?logout=true">Logout</a><br />'; echo 'Welcome! This is protected content!' . "<br />"; } if(!Auth::checkLoggedIn()) : ?> <h1>Sign In</h1> <?php if(isset($userName) && isset($password)){if($auth === "invalidPassword"){echo '<span class="error">Invalid username or password</span>';}} ?> <form name="login" method="post" action="index.php" id="loginForm"> <ul> <li> <input placeholder="Username" type="text" name="userName" id="userName" class="login" /> </li> <li> <input placeholder="Password" type="password" name="password" id="password" class="login" /> </li> <?php if(isset($userName) && isset($password)){ echo $auth . "<br />"; if($auth === "bruteForce"){ echo $auth; require_once('includes/recaptchalib.php'); // Get a key from https://www.google.com/recaptcha/admin/create $publickey = "xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; $privatekey = "xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; $resp = null; $error = null; if(isset($_POST["recaptcha_response_field"])){ $resp = recaptcha_check_answer ($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]); if ($resp->is_valid) { Auth::checkLoggedIn(); $auth = Auth::verifyPass($userName,$password,1); } else { $auth = Auth::verifyPass($userName,$password,0); //$captchaResponse = 2; } } echo recaptcha_get_html($publickey, $error); if($auth === "invalidCaptcha"){ echo "Invalid Captcha Response. Please try again."; } } } if(isset($auth)){echo $auth;} ?> <div class="clearAll"> </div> <li id="submit"> <input type="submit" value="Login" id="loginBtn" class="login" /> </li> <li id="reset"> <input type="reset" value="Reset" id="resetBtn" class="login" /> </li> </ul> </form> <div class="clearAll"> </div> <h1>New User?</h1> <p><a href="register.php">Sign Up!</a></p> <?php endif; ?> <div class="clearAll"> </div> <?php include('includes/footer.php'); ?> </body> </html> -
这是登录功能
public static function verifyPass($username,$password,$captchaResponse = 3){ $authenticatedUser = FALSE; $bruteTest = self::_bruteTest($username); if($bruteTest === TRUE && $captchaResponse === 3){ $status = "bruteForce"; return $status; } else if($bruteTest === TRUE && $captchaResponse === 0){ //The brute force check was positive and the captcha response failed //Don't even try to log in because the captcha failed. $status = "invalidCaptcha"; return $status; } else if ($bruteTest === TRUE && $captchaResponse === 1){ //The brute force check was positive and the captcha response was successful //Try to log in now. $continueLogin = TRUE; } else if($bruteTest === FALSE){ //The bruteTest was negative, proceed with login. $continueLogin = TRUE; } if($continueLogin === TRUE){ try{ $connection = Database::getDbConnection(); if($connection){ $query = "SELECT usr_name, usr_pass, usr_salt, uid, email_pri FROM users WHERE usr_name=? LIMIT 1"; $stmt = $connection->prepare($query); $stmt->execute(array($username)); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); if($stmt->rowCount() === 0){$authenticatedUser = FALSE;} //Username was not found We are not going to say which was incorrect, only that the "username or password was incorrect" if($results){ $resultsArray = $results[0]; $connection = null; echo "<br />"; $dbUserName = $resultsArray['usr_name']; $dbPass = $resultsArray['usr_pass']; $dbSalt = $resultsArray['usr_salt']; $dbUid = $resultsArray['uid']; $dbEmail = $resultsArray['email_pri']; $passHash = hash('sha512',$password); $passToCheck = hash('sha512',$dbSalt.$passHash); if($passToCheck != $dbPass){ $authenticatedUser = FALSE; //Password did not match. We are not going to say which was incorrect, only that the "username or password was incorrect" } else if ($passToCheck === $dbPass && $username === $dbUserName){ $authenticatedUser = TRUE; } } }else if(!$results){$authenticatedUser = FALSE;} } catch (PDOException $e) { echo "Error: " . $e->getMessage() . "<br />"; die(); } try{ if($authenticatedUser === FALSE){ //Log the failed attempt into the database $remoteIp = $_SERVER['REMOTE_ADDR']; try { $connection = Database::getDbConnection(); if($connection){ $query = "INSERT INTO `login_attempts`(`usr_name`, `usr_ip`) VALUES (:usr_name,INET_ATON(:usr_ip))"; $stmt = $connection->prepare($query); $stmt->execute(array(':usr_name' => $username, ':usr_ip' => $remoteIp)); } $connection = null; } catch (PDOException $e){ echo "Error: " . $e->getMessage() . "<br />"; die(); } $status = "invalidPassword"; return $status; exit(); }else if($authenticatedUser === TRUE){ //Clear login attempts from the database self::_clearAttempts($username); //Start the session (if not already started somehow. session and cookie expiration need to be adjusted so that the session does not persist after browser close) if(!isset($_SESSION)){ session_start(); } //Set the session variables $_SESSION['userIp'] = $_SERVER['REMOTE_ADDR']; $_SESSION['userName'] = $dbUserName; $_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT']; $session_name = 'sec_session_id'; $httponly = TRUE; $cookieParams = session_get_cookie_params(); session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $httponly); session_name($session_name); } } catch (PDOException $e) { echo "Error: " . $e->getMessage() . "<br />"; die(); } //End $continueLogin statement below } }
【问题讨论】:
-
+1 表示这种长且风格不错的书面作品,但您的代码应该被格式化。
-
感谢您的输入,对于缺少格式,我深表歉意。我仍然习惯于在 Stack Overflow 上发布代码。我已经编辑了我的帖子以包含正确的格式。
-
请注意,验证码(包括 reCAPTCHA)不是可靠的防御措施。期待 CAPTCHA 的机器人几乎不会被它们拖慢。不过,总比没有好。您也可以考虑在每次连续登录失败时等待越来越长的时间。
-
感谢您的建议。我的目标是最初让 reCAPTCHA 与这个登录系统一起工作。一旦它起作用,我计划在最后阶段使用 reCAPTCHA 逐步限制登录尝试。我只需要先确定 reCAPTCHA 的实施。我对为什么登录页面需要刷新以重新提交数据以显示受保护的内容感到更加困惑。
标签: php forms login captcha recaptcha