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

如何验证Google reCAPTCHA V3响应?PHP前后端集成故障排查

解决Google reCAPTCHA V3与PHP后端的集成验证问题

你的代码核心问题是前端没有将reCAPTCHA生成的响应值传递给后端,而且当前的执行逻辑也不够严谨,导致后端无法接收到验证所需的参数。下面是完整的修复方案,我会一步步拆解说明:

一、修正前端代码

reCAPTCHA V3是无交互的隐形验证,需要把验证得到的响应值存入隐藏表单字段,随表单一起提交给后端。同时建议在表单提交时触发验证,避免响应值过期:

<html>
<head>
    <!-- 加载reCAPTCHA脚本,替换成你的site key -->
    <script src='https://www.google.com/recaptcha/api.js?render=你的Site_Key'></script>
</head>
<body>
    <form id="contactForm" action="verify.php" method="post">
        <input type="text" name="name" placeholder="Your name" required>
        <input type="email" name="email" placeholder="Your email address" required>
        <textarea name="message" placeholder="Type your message here...." required></textarea>
        <!-- 添加隐藏字段存储reCAPTCHA响应值 -->
        <input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">
        <input type="submit" name="submit" value="SUBMIT">
    </form>

    <script>
        // 表单提交时触发reCAPTCHA验证
        document.getElementById("contactForm").addEventListener("submit", function(e) {
            e.preventDefault(); // 先阻止表单默认提交

            grecaptcha.ready(function() {
                // 执行验证,替换成你的site key和action名称(要和后端一致)
                grecaptcha.execute('你的Site_Key', { action: 'contact_submit' }).then(function(token) {
                    // 将响应值存入隐藏字段
                    document.getElementById('g-recaptcha-response').value = token;
                    // 提交表单
                    document.getElementById("contactForm").submit();
                });
            });
        });
    </script>
</body>
</html>

前端关键调整点:

  • 添加了id="g-recaptcha-response"的隐藏input,用于存储验证token
  • 监听表单提交事件,先执行reCAPTCHA验证,拿到token后再提交表单
  • 确保action参数前后端保持一致(这里用了contact_submit,你可以自定义但要统一)

二、修正后端Verify.php代码

后端需要接收前端传递的token,调用Google的验证接口,同时还要验证action匹配度、设置分数阈值(V3会返回0-1的分数,建议设置≥0.5的阈值拦截机器人)。另外,file_get_contents可能在部分服务器环境被禁用,用cURL更可靠:

<?php
// 检查是否收到reCAPTCHA响应值
if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])) {
    // 替换成你的Secret Key
    $secretKey = "你的Secret_Key";
    $captchaResponse = $_POST['g-recaptcha-response'];
    $userIp = $_SERVER['REMOTE_ADDR']; // 获取用户IP,可选但建议传递

    // 构建验证请求参数
    $params = [
        'secret' => $secretKey,
        'response' => $captchaResponse,
        'remoteip' => $userIp
    ];

    // 用cURL发送请求(比file_get_contents更稳定)
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $verifyResponse = curl_exec($ch);
    curl_close($ch);

    $responseData = json_decode($verifyResponse);

    // 验证核心条件:成功、action匹配、分数达标
    if($responseData->success && $responseData->action === 'contact_submit' && $responseData->score >= 0.5) {
        echo "验证通过!表单可以正常处理";
        // 这里写你的表单逻辑,比如发送邮件、存储数据等
    } else {
        // 输出具体错误信息方便调试
        $errors = isset($responseData->{'error-codes'}) ? implode(', ', $responseData->{'error-codes'}) : '未知错误';
        echo "验证失败:" . $errors . ",分数:" . $responseData->score;
    }
} else {
    echo "未收到reCAPTCHA验证响应,请检查前端代码";
}
?>

后端关键调整点:

  • 使用cURL替代file_get_contents,提升兼容性和稳定性
  • 增加了action匹配验证,确保请求来自预期的操作
  • 增加了分数阈值判断(≥0.5),过滤低可信度的请求
  • 输出具体错误码,方便调试问题

三、注意事项

  1. 替换密钥:一定要把代码中的你的Site_Key和你的Secret_Key替换成Google reCAPTCHA控制台获取的真实密钥
  2. Action一致性:前后端的action参数必须完全一致,否则验证会失败
  3. 分数阈值:根据你的业务场景调整分数阈值,比如登录、支付等敏感操作可以设置≥0.7
  4. 调试技巧:如果验证失败,可以打印$responseData查看具体错误码,方便定位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:29:00