如果 Google ReCaptcha 未通过,我将如何禁止用户登录?

How would I go about not allowing a user to login if Google ReCaptcha doesn't pass?

首先,我很难将 Google ReCaptcha 绑定到我的登录表单中。只是为了一些背景信息,这就是所有 运行 在具有 SSL 证书的实时网络服务器上,我有正确的站点和密钥以及所有爵士乐。

这是我的登录表单:

<html>

<head>

<script src='https://www.google.com/recaptcha/api.js'></script>

</head>

<body>

<br />
<p>Please log in to your account below:</p>

<form action="index.php" method="post" target="_self">
    <b>User Name:</b><br>
    <input type="text" size="20" name="userid"><br />
<br />
    <b>Password:</b><br>
    <input type="password" size="20" name="password"><br />
<br />

<div class="g-recaptcha" data-sitekey="_MY PUBLIC SITE KEY_"></div>
<br />
    <input type="submit" name="submit" value="Login">
    <input type="hidden" value="validate" name="content">
</form>

以及我要验证的脚本:

<?php

if (isset($_POST['submit'])) {
    $userid = $_POST["userid"];
    $password = $_POST["password"];
    $secretkey = "_MY SECRET KEY_";
    $responsekey = $_POST["g-recaptcha-response"];
    $useripaddress = $_SERVER["REMOTE_ADDR"];

    $url = "https://www.google.com/recaptcha/api/siteverify?secret={$secretkey}&response={$responsekey}&remoteip={$useripaddress}";
    $response = file_get_contents($url);
    echo $response;
}

require_once("scripts/thecrab.php");

$userid = htmlspecialchars($_POST['userid']);
$password = htmlspecialchars($_POST['password']);

$query = "SELECT userid from users where userid = ? and password = PASSWORD(?)";
$stmt = $pdo->prepare($query);
$stmt->execute([$userid, $password]);

if (!$stmt->rowCount() & $response->success == 0) {
    echo "<h2>Sorry, your user account was not validated.</h2><br>\n";
    echo "<a href=\"index.php?content=login\">Try again</a><br>\n";
    echo "<a href=\"index.php\">Return to Home</a>\n";
} else {
    $_SESSION['valid_recipe_user'] = $userid;
    echo "<h2>Log In Successful</h2><br>\n";
    echo "<a href=\"index.php\"><img src=\"images/image-11.png\"></a>\n";
}
?>

下面是我遇到的几个问题。如果您注意到,在我验证信息的页面顶部,我有 回声$响应; 那里严格用于测试目的,这样我就可以看到 ReCaptcha 返回的结果是真还是假,但即使在填写 ReCaptcha 时,它总是返回 false,无论我的安全设置是什么 Google网站。我在验证周围添加了预标记,以便它可以以更易于阅读的形式吐出结果,即使我填写了验证码,我也会受到欢迎:

{
    "success": false,
    "error-codes": [
        "missing-input-response"
    ]
}

现在,因为我被一个永恒的 "false" 困住了,我决定试一试 if 语句并实施,如果成功为假(即 0)则不登录,否则登录。非常简单,您可以在我的验证页面底部的 if 语句中看到:

if (!$stmt->rowCount() & $response->success == 0)

到目前为止一切顺利,我 FTP 将其发送到服务器,刷新并试一试。但是这次我得到一个错误,它指出变量 $response 是未定义的。好吧,我在验证页面的顶部定义了变量,我说:

if (isset($_POST['submit'])) // Checks to see if the form was submitted

当我点击名称为 "submit" 的登录按钮时它被提交了,所以它看到提交设置了登录值,所以它执行 if 后面的内容(你知道如何 PHP 有效),底部是它定义 $response 的地方。据我所知,使用PHP,变量定义在哪个块中并不重要,只要它被执行,它就可以在任何地方使用。

总而言之,我遇到的问题是:

  1. ReCaptcha 的计算结果始终为 False
  2. 抛出错误,指出 $response 尽管已定义但仍未定义
  3. 与#2 相关,由于变量未定义,因此无法执行 if 语句。

我已经尝试了几乎所有的技能。

再次检查您传递给 https://www.google.com/recaptcha/api/siteverify 的参数。 response参数必须是responSe而不是respone。

这会导致服务器 return 出现错误 - "missing-input-response" 意味着您没有传递 "g-recaptcha-response" 参数

现在响应正常:

  1. file_get_contents 将 return 一个包含 JSON 响应的字符串。如果您想以您在此处访问的方式访问 JSON 中的成功值

    if (!$stmt->rowCount() & $response->success == 0) {
    

    那么您必须先使用 json_decode 从字符串中创建一个对象。

  2. 同一行中的 if 逻辑使用按位 AND 运算符,因为您使用的是单个 & 而不是 &&

  3. 逻辑本身 - 当前如果没有用户帐户存在并且重新验证失败则将出现错误,否则它是有效的。问题是,如果没有用户但 recaptcha 正常,则用户有效,如果用户正常且 recaptcha 失败,则用户仍然有效。所以我猜你打算使用 OR 而不是 AND:

    if (!$stmt->rowCount() || $response->success == 0) {