如何通过 javascript 检测重新验证码站点密钥是否有效?

How to detect if a re-Captcha site key is valid via javascript?

我正在尝试通过 javascript 检测 google 重新验证码的 'Invalid site key' 错误,以便将错误报告给服务器以供进一步处理。我正在使用显式渲染模式并调用 api 函数 grecaptcha.render('iframeid', {'site-key':'xxx'}); 尽管此函数不会 return 任何错误响应或抛出异常,即使它加载以下内容也是如此:

我不能简单地读取加载的错误文本,因为它是在不同域的 iframe 中加载的。无论如何,是否可以通过 javascript 或服务器端自动检测无效的站点密钥?

编辑 最终解决方案是使用 phantomjs 加载测试页面并解析 recaptcha

的 html

Google 没有提供验证 site key 的方法,你也不能 hack/access reCaptcha html 代码,因为 reCapthca 是在 iframe 中,框架的代码无法通过客户端编程访问。

Its a common mistake to forget to update the allowable domains in the dashboard when pushing a new site live.

由于您管理多个域,我建议您为您使用的所有域使用一个 站点密钥。为此使用 secure token

破解

另一种选择可能是您开发一个脚本,该脚本将访问感兴趣的站点,制作 screenshot/snap 加载的 reCaptcha,应用 OCR(例如使用 this)和 return 如果 站点密钥 有效或无效,则结果。

由于 Google 没有提供官方的检查方法,我刚刚实施了一个解决方法,对 Google 的 Recaptcha URL 执行 GET 请求.我已经使用 PHP,但不难调整 JavaScript 的解决方案,尽管它可能因 Same Origin Policy 导致的跨源错误而结束。因此,如果有人使用 JavaScript 测试此解决方案,请告诉我们它的运行情况(如果它不起作用,总是可以 运行 一个 AJAX 到您自己的服务器并检查有效性直接从您的服务器)。

除此之外,就我而言,我使用的是 Invisible ReCaptcha v2,但我认为这种方法也可以用于其他 Recaptchas。

  1. 首先,您应该安装 URL。我找不到确定这个“co”参数的方法,我也不知道它是什么意思。但看起来不同的网站都接受不同的价值观。您可以通过在您的页面上添加 Recaptcha 代码(无论它是否使用有效键)来查找此值,然后检查生成的 <iframe>.
  2. 上的 src 参数
        $recaptcha_url = sprintf(
            'https://www.google.com/recaptcha/api2/anchor?ar=1&k=%s&co=%s&hl=%s&size=%s',
            RECAPTCHA_SITE_KEY,
            '<co_param_value>',
            'en-US',
            'invisible'
        );

在 JavaScript 上会是这样的:

    recaptcha_url = 'https://www.google.com/recaptcha/api2/anchor?ar=1&k=' + RECAPTCHA_SITE_KEY + ' &co=' + CO_VALUE + '&hl=en-US&size=invisible';

如果您不使用 Invisible Recaptcha,size 参数必须不同。但是您也可以省略它,因为至少在我的测试中,没有必要检查站点密钥是否有效(语言参数相同hl)。

  1. 然后,您对此 URL 执行 GET 请求。在 PHP 上,您可以使用 cURL. If it's Wordpress, you can use wp_remote_get。在 JavaScript(jQuery,实际上),你可以使用 $.get.
    $.get( recaptcha_url, function(data, status){ ... });
  1. 最后,您检查响应正文是否包含字符串 'Recaptcha.anchor.ErrorMain.init'。这意味着当 Recaptcha 站点密钥对当前域无效时,Google 处理错误,并且此字符串出现在响应正文中(实际上,任何 ReCaptcha 错误都会导致此字符串,因此请记住这是一种解决方法).

如果您使用的是 Wordpress,则可以使用 wp_remote_retrieve_body。像这样:

    $response      = wp_remote_get( $recaptcha_url );
    $response_body = wp_remote_retrieve_body( $response );

    if( strpos( $response_body, 'recaptcha.anchor.ErrorMain.init' ) !== false ) {
        // Site is not valid for current Recaptcha Keys
    }

在 JavaScript,我想你可以检查在 $.get.

收到的 data 变量

不幸的是,这不是一个强有力的解决方案。 Google 可以更改请求和响应,这可能会破坏实现。但是我们对此无能为力,因为没有官方电话来检查密钥。