///
reCAPTCHA v2 API 集成:如何接入和使用
CapMonster Cloud 团队
CapMonster Cloud 团队
自动化专家
July 2, 2026
9 分钟
请查看本网站所提供内容的使用条款。

reCAPTCHA v2 API 集成:如何接入和使用

对于 2026 年的 Web 开发者来说,集成 reCAPTCHA v2 API 是一项标准的安全任务。Google 的 reCAPTCHA v2 有两种形式:大家熟悉的“我不是机器人”复选框,以及在后台静默触发的隐形模式。在这两种情况下,其机制都是一样的——客户端小组件会生成一个一次性令牌,而您的服务器会在处理请求之前,通过 Google 的 siteverify API 对其进行验证。

本指南涵盖完整的集成流程:站点注册、HTML 小组件嵌入、服务器端令牌验证,以及常见错误处理。本文还会讨论自动化场景——当 reCAPTCHA v2 出现在无法由人工参与的工作流中时,该如何应对。如需更广泛的概览,请先查看我们的 reCAPTCHA v2 求解页面

 

专家观点 — Vladlen Vlasov,开发与 Web 安全专家

“到了 2026 年,reCAPTCHA v2 的集成细节依然重要,正是因为这个小组件部署得如此广泛。服务器端验证步骤处理错误——或者完全跳过它——仍然是我在开发者论坛上看到的最常见安全问题之一。客户端小组件只是整个故事的一半。”

 

robots
立即开始自动化您的工作流 reCAPTCHA v2

什么是 reCAPTCHA v2,它如何工作?

reCAPTCHA v2 是 Google 提供的一项 CAPTCHA 服务,用于区分真实用户和自动化机器人。它分两个阶段运行:客户端阶段由浏览器渲染小组件,并在用户交互后生成响应令牌;服务器端阶段则由您的后端通过 Google 的 API 验证该令牌。

900ff128cf18f23d670e309c4d71bc51.png

复选框版本会要求用户点击“我不是机器人”。Google 的风险分析引擎会在后台运行;如果评分处于临界范围,就会显示图片验证挑战。隐形版本则跳过可见复选框,并在配置的操作上自动触发,通常是在表单提交时;只有当风险评分要求这样做时,才会显示挑战。

recaptcha.png

在做集成决策时,理解 v2 与其其他版本之间的差异非常重要。有关更详细的技术拆解,请参阅 reCAPTCHA v2 vs v3 vs Enterprise: Key Differences


集成 reCAPTCHA v2 之前的前提条件

在开始编码之前,您需要从 Google 获取两样东西:Site KeySecret Key

注册您的站点

  1. 前往 google.com/recaptcha/admin/create,并使用 Google 账号登录。
  2. 输入标签,选择 reCAPTCHA v2,然后选择复选框版本或隐形版本。
  3. Domains 下添加您的域名。如果您在本地测试,也请添加 localhost
  4. 选择一个现有的 Google Cloud Platform project,或者新建一个。reCAPTCHA Classic 已于 2026 年初迁移到 GCP,因此现在所有密钥都归属于某个 GCP 项目。
  5. 接受服务条款,然后点击 Submit
unnamed-8.png

Google 会显示两个密钥:

  • Site Key —— 公开,可嵌入到您的 HTML 中。
  • Secret Key —— 私密,仅供您的服务器使用。切勿在客户端代码中暴露它。

google-recaptcha-site-secret-keys.jpg (1791×1040).png

在生产环境中,您需要使用 HTTPS。reCAPTCHA 在开发阶段可以通过 localhost 上的 HTTP 运行,但在线部署需要安全连接,并且需要具备到 www.google.com 的出站 HTTPS 访问能力以完成验证。


将 reCAPTCHA v2 添加到您的 HTML 表单

加载 reCAPTCHA 脚本

将以下脚本标签放在页面的 <head> 中,或放在结束 </body> 标签之前:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

async defer 属性可防止脚本阻塞页面渲染。

使用 data-sitekey 放置小组件

对于标准复选框版本,请在表单中添加一个带有 g-recaptcha 类和您的 Site Key 的 div

<form method="POST" action="/submit">
  *<!-- your form fields -->*
  <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
  <button type="submit">Submit</button>
</form>

页面加载后,Google 的脚本会将这个 div 替换为交互式小组件。用户成功完成交互后,它会填充一个名为 g-recaptcha-response 的隐藏输入字段,并随表单一起提交。

隐形版本设置

隐形版本附加在您的提交按钮上,而不是渲染一个可见的小组件:

<form method="POST" action="/submit">
  *<!-- your form fields -->*
  <button
    class="g-recaptcha"
    data-sitekey="YOUR_SITE_KEY"
    data-callback="onSubmit"
    data-action="submit"
    type="submit">
    Submit
  </button>
</form>
<script>
  function onSubmit(token) {
    document.getElementById('your-form-id').submit();
  }
</script>

data-callback 函数会接收令牌,并触发实际的表单提交。如果没有这个回调,表单在 reCAPTCHA 完成后将不会提交。

robots
立即开始自动化您的工作流 reCAPTCHA v2

使用 siteverify API 进行服务器端验证

嵌入小组件只是安全集成 reCAPTCHA v2 的前半部分。您必须在服务器上验证令牌。未经过验证的令牌无法提供任何机器人防护。

流程很直接:用户与小组件交互 → Google 向浏览器返回一个 g-recaptcha-response 令牌 → 该令牌随表单一起提交到您的服务器 → 您的服务器将令牌和您的 Secret Key 通过 POST 发送到 https://www.google.com/recaptcha/api/siteverify → Google 返回一个 JSON 结果。

向 siteverify 发送 POST 请求

该验证端点接受一个带有两个必需参数的 POST 请求:

参数说明
secret您的 Secret Key
response来自客户端的 g-recaptcha-response 令牌
remoteip (可选)用户的 IP 地址

解析 JSON 响应并处理错误

验证成功时会返回:

{
  "success": true,
  "challenge_ts": "2026-06-17T10:00:00Z",
  "hostname": "yourdomain.com",
  "error-codes": []
}

验证失败时会返回 "success": false,以及一个或多个错误代码:

错误代码含义
missing-input-secret未发送 Secret Key 参数
invalid-input-secretSecret Key 不正确或格式不合法
missing-input-response客户端未提交令牌
invalid-input-response令牌无效或格式不合法
timeout-or-duplicate令牌已过期或已被使用

在继续处理之前,始终检查 success === true。不要仅仅依赖没有错误代码这一点。

PHP 服务器端验证示例

下面的示例展示了完整的服务器端验证函数。请将 $YOUR_SECRET_KEY 替换为您的实际 Secret Key。

<?php
declare(strict_types=1);
function verifyRecaptchaV2(
    string $token,
    string $YOUR_SECRET_KEY,
    ?string $remoteIp = null
): array {
    if ($token === "") {
        return [
            "ok" => false,
            "message" => "reCAPTCHA token was not received.",
            "data" => null,
        ];
    }
    $postFields = [
        "secret" => $YOUR_SECRET_KEY,
        "response" => $token,
    ];
    if ($remoteIp !== null && $remoteIp !== "") {
        $postFields["remoteip"] = $remoteIp;
    }
    $ch = curl_init("https://www.google.com/recaptcha/api/siteverify");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($postFields),
        CURLOPT_TIMEOUT => 10,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
    ]);
    $responseBody = curl_exec($ch);
    $curlError = curl_error($ch);
    $httpCode = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);
    if ($responseBody === false || $curlError !== "") {
        return [
            "ok" => false,
            "message" => "Failed to send a request to Google reCAPTCHA.",
            "data" => null,
        ];
    }
    if ($httpCode < 200 || $httpCode >= 300) {
        return [
            "ok" => false,
            "message" => "Google reCAPTCHA returned an unexpected HTTP status.",
            "data" => null,
        ];
    }
    $data = json_decode($responseBody, true);
    if (!is_array($data)) {
        return [
            "ok" => false,
            "message" => "Failed to parse the Google reCAPTCHA response.",
            "data" => null,
        ];
    }
    if (!empty($data["success"])) {
        return [
            "ok" => true,
            "message" => "reCAPTCHA verification passed successfully.",
            "data" => $data,
        ];
    }
    $errors =
        isset($data["error-codes"]) && is_array($data["error-codes"])
            ? implode(", ", $data["error-codes"])
            : "unknown_error";
    return [
        "ok" => false,
        "message" => "reCAPTCHA verification failed: " . $errors,
        "data" => $data,
    ];
}

在 JavaScript 中使用 reCAPTCHA v2

集成 reCAPTCHA v2 之后,您可以直接通过 JavaScript API 与该小组件交互。下表涵盖了关键方法和回调。

方法 / 回调用途
grecaptcha.render()将小组件手动渲染到一个容器元素中
grecaptcha.getResponse()获取当前响应令牌(如果尚未完成验证,则为空字符串)
grecaptcha.reset()重置当前挑战,以便用户再次完成验证
callback当用户成功完成挑战时触发;会接收该令牌
expired-callback当已完成验证的令牌在提交前过期时触发

实用的 JavaScript 示例

获取生成的令牌:

const token = grecaptcha.getResponse();

在请求失败后重置小组件:

grecaptcha.reset();

动态渲染小组件(适用于 SPA,或容器是在页面加载后注入到 DOM 中的情况):

function onSolved(token) {
  document.querySelector('textarea[name="g-recaptcha-response"]').value = token;
  document.getElementById('contact-form').submit();
}
grecaptcha.render('captcha-container', {
  sitekey: 'YOUR_SITE_KEY',
  callback: onSolved,
  'expired-callback': () => grecaptcha.reset(),
});

在提交前检查用户是否已完成挑战:

if (!grecaptcha.getResponse()) {
  alert('Complete the CAPTCHA first.');
  return;
}

expired-callback 很容易被忽视:如果用户完成了挑战,但在提交前等待超过两分钟,令牌会静默过期。如果没有这个处理程序,您的表单将提交一个无效令牌,并在服务器端验证时因 timeout-or-duplicate 而失败。


常见集成错误及修复方法

即使是看似直接的 reCAPTCHA v2 集成,也可能以一些可预见的方式出问题。

问题可能原因修复方法
小组件未渲染缺少脚本标签,或被 CSP 阻止在您的 CSP script-srcframe-src 中添加 https://www.google.com
验证时出现 invalid-input-secretSecret Key 错误,或来自错误的项目检查 Admin Console,并确认您使用的是正确的 Secret Key
timeout-or-duplicate令牌已超过 \~2 分钟,或被提交了两次重新提示用户完成验证,并且绝不要重复使用令牌
invalid-input-response令牌未转发到服务器记录 req.body['g-recaptcha-response'],以确认它到达了您的处理程序
控制台中的域名不匹配错误域名未在 Admin Console 中注册在 reCAPTCHA Admin 设置中添加准确的域名
小组件在 SPA 路由切换后失效DOM 操作后未重新渲染小组件调用 grecaptcha.render(),或使用 grecaptcha.reset() 重置
AJAX 表单中出现 missing-input-responseAJAX 负载中未包含令牌字段读取 grecaptcha.getResponse(),并将其附加到您的 fetch 或 XHR 请求体中

绝不要将缺失令牌视为已通过验证。如果缺少 g-recaptcha-response,请立即拒绝该请求。


用于自动化的 reCAPTCHA v2:Solver API 方案

您刚刚将 reCAPTCHA v2 添加到您的站点中——现在该测试它在实际环境中的表现了。与其在每次检查时都手动完成挑战,不如将您的 reCAPTCHA 公开参数发送到 CapMonster Cloud,接收一个有效令牌,并使用它来测试您集成中的不同场景。

CapMonster Cloud reCAPTCHA v2 求解 API 遵循四步模式:

  1. 提交一个任务,其中包含目标页面 URL 和 sitekey
  2. 轮询获取结果。
  3. 将返回的令牌插入到 g-recaptcha-response 中。
  4. 在令牌过期前提交表单。

CapMonster Cloud 提供了一个 reCAPTCHA v2 solver API,遵循这种返回令牌的模式。如需实际操作演示,请参阅 如何在 2026 年解决 reCAPTCHA v2:可行方法。如果您正在比较不同的服务提供商,文章“如何在 2026 年选择最佳的 ReCAPTCHA v2 求解器”提供了实用的指导。

 

关键洞察 — Vladlen Vlasov,开发与 Web 安全专家

“向站点中添加 reCAPTCHA 的开发者,与在自动化流水线中遇到它的自动化工程师,解决的是镜像式的问题。理解这两个方面,会让您在每一方面都做得更好:更严密的服务器端集成更难被绕过,而结构良好的 solver API 集成在令牌过期或页面变化时也会更可靠。”

 

robots
立即开始自动化您的工作流 reCAPTCHA v2

FAQ

最常见的原因是令牌过期和域名不匹配。令牌的有效期大约为两分钟,因此在验证前如果发生延迟,就可能导致验证失败。域名不匹配是指在 Admin Console 中注册的域名与加载小组件的域名不一致。

 

Site Key 是公开的,应放在您的 HTML 中。Secret Key 是私密的,只应在您的服务器调用 'siteverify' 时使用。如果 Secret Key 暴露在客户端代码中或公开代码仓库中,您的验证流程就会被破坏。

 

可以,但您需要显式管理小组件。在 SPA 中,路由变化不会自动重新触发小组件渲染,因此应在视图挂载时使用 'grecaptcha.render()',并在提交失败后使用 'grecaptcha.reset()'

 

在用户完成验证后,使用 'grecaptcha.getResponse()' 读取令牌,并将其包含在您的 fetch 或 XHR 请求体中。在服务器端,像处理普通表单 POST 一样对其进行验证。

 

结论

正确集成 reCAPTCHA v2 API 需要两个部分:一个正常工作的客户端小组件,以及一个真正用于控制请求处理的服务器端 siteverify 校验。对于大多数项目来说,复选框版本是更稳妥的起点——更容易实现、更容易调试,也更便于用户理解。隐形版本适用于“减少用户操作不便”是可衡量优先目标、并且您的回调流程足够稳固的场景。如果您的自动化工作流需要以编程方式处理 reCAPTCHA v2,那么令牌注入模式是直接明了的——主要约束在于令牌生命周期,因此应尽快获取并提交。


为您的自动化流水线获取 reCAPTCHA v2 令牌

如果您的自动化工作流会大规模遇到 reCAPTCHA v2,手动处理是无法持续的。CapMonster Cloud 提供了一个 reCAPTCHA v2 solver API,适配本指南中描述的同一类集成模式——发送 sitekey 和页面 URL,接收一个可直接使用的令牌。

  • 兼容浏览器自动化和直接 HTTP 工作流
  • 用于任务创建和结果获取的简洁 API 模式
  • 面向与 reCAPTCHA 相关的自动化使用场景构建

请在 reCAPTCHA v2 概览页面 查看支持的 reCAPTCHA v2 工作流。


NB: 请注意,本产品仅用于对您自身的网站以及您依法拥有访问权限的资源进行自动化测试
ItGuy
geear
面向软件开发者的联盟计划
通过用户识别验证码的消费获取高达 30% 的返佣。
✅ 请求已发送
感谢您对我们的合作伙伴计划感兴趣!我们将在 7 个工作日内与您联系。
请求加入
填写表格以提交申请加入合作伙伴计划。
更多文章