reCaptcha V3 仅在首次提交表单时验证失败

reCaptcha V3 fails validation on first form submission only

我正在尝试设置 reCaptcha v3,它可以正常工作。由于某种原因,我第一次提交表单时失败了,但是从第二次提交开始就可以了。我不明白为什么会这样?

<script src="https://www.google.com/recaptcha/api.js?render=MY_SITE_KEY"></script>
<script>
grecaptcha.ready(function () {
    grecaptcha.execute('MY_SITE_KEY', { action: 'contact' }).then(function (token) {
        var recaptchaResponse = document.getElementById('captcha-response');
        recaptchaResponse.value = token;
    });
});
</script>




 <input type="hidden" name="captcha-response" id="captcha-response">

PHP

$verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['captcha-response']);
$responseData = json_decode($verifyResponse);

     if(!$responseData->score < 0.5) {
      $message .= "Verification failed " . $responseData->score;
  }

当我第一次提交表单时,我收到验证错误,但我的分数是 0.9。

为什么你加了“!”使用“$responseData->score”?您可能需要用以下内容替换您的条件:

替换为:

if(!$responseData->score < 0.5) {
    $message .= "Verification failed " . $responseData->score;
}

有了这个:

if($responseData->score < 0.5) {
    $message .= "Verification failed " . $responseData->score;
}

P.S:以下代码需要几秒钟才能正确加载并获得 "captcha-reponse" 代码,因此您可能需要禁用所有提交按钮并等待直到获得 "captcha-reponse"启用表单中的提交按钮,或者您需要实施另一种方式来延迟提交,只有在您获得 "captcha-response" 代码后才执行,否则您将不断收到 "missing-input-response" 错误消息

<script src="https://www.google.com/recaptcha/api.js?render=MY_SITE_KEY"></script>
<script>
  grecaptcha.ready(function() {
    grecaptcha.execute('MY_SITE_KEY', {
      action: 'contact'
    }).then(function(token) {
      var recaptchaResponse = document.getElementById('captcha-response');
      recaptchaResponse.value = token;
    });
  });
</script>

您应该在发生错误表单验证后重新生成 reCaptcha 令牌。 令牌 reCaptcha 仅一次有效。

因此,您有两种选择来解决此问题。

1。发生错误时重新加载页面

这是最简单的方法。您只需在出现表单验证错误时重新加载页面。

当然,这会触发reCaptcha生成新的token。

2。使用 AJAX 处理(非重新加载页面)

这是最好的方法,因为这将帮助用户不丢失表单数据并继续填写表单。

所以,这是你应该做的。

<!-- Put this hidden input inside of your form tag -->
<input name="_recaptcha" type="hidden">

<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITEKEY_HERE"></script>
<script>
  // This will generate reCaptcha token and set to input hidden
  const generateRecaptcha = function() {
    grecaptcha.execute(
      "YOUR_SITEKEY_HERE", {
        action: "YOUR_ACTION_NAME"
      }).then(function(token) {
      if (token) {
        document.querySelector("input[name='_recaptcha']").value = token;
      }
    });
  }

  // Call it when page successfully loaded
  grecaptcha.ready(function() {
    generateRecaptcha();
  });

  // Do your AJAX code here
  $.ajax({
    url: "https://example.com",
    success: function(response) {
      console.log(response);
    },
    error: function(error) {
      // Call again the generator token reCaptcha whenever error occured
      generateRecaptcha();
    }
</script>

不要忘记输入您的站点密钥和您的操作名称。确保操作名称与您的后端操作名称匹配。

Medium Article