简体   繁体   English

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

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

I'm attempting to detect the 'Invalid site key' error for googles re-Captcha via javascript so the error can be reported to the server for further handling.我正在尝试通过 javascript 检测谷歌重新验证码的“无效站点密钥”错误,以便可以将错误报告给服务器以进行进一步处理。 I'm using the explicit rendering mode and calling the api function grecaptcha.render('iframeid', {'site-key':'xxx'});我正在使用显式渲染模式并调用 api 函数grecaptcha.render('iframeid', {'site-key':'xxx'}); although this function doesn't return any error response or throw an exception even if it loads the following:尽管此函数即使加载以下内容也不会返回任何错误响应或抛出异常: 在此处输入图片说明

I can't simply read the loaded error text either as it's loaded in an iframe on a different domain.我不能简单地读取加载的错误文本,因为它是在不同域的 iframe 中加载的。 Is there anyway to detect an invalid site key automatically, either via javascript or server side?无论如何通过javascript或服务器端自动检测无效的站点密钥?

Edit Final solution was to load a test page with phantomjs and parse the html of the recaptcha编辑最终的解决方案是使用 phantomjs 加载一个测试页面并解析 recaptcha 的 html

Google does not provide methods to verify site key , neither you can hack/access reCaptcha html code by JS since the reCapthca is in an iframe and frame's code is not programmatically accessible client-side. Google 不提供验证站点密钥的方法,您也无法通过 JS 破解/访问 reCaptcha html 代码,因为 reCapthca 位于 iframe 中,并且框架的代码不能以编程方式访问客户端。

Its a common mistake to forget to update the allowable domains in the dashboard when pushing a new site live.在推送新站点时忘记更新仪表板中允许的域是一个常见的错误。

Since you manage multiple domains I'd recommend you to use one site key for all of the domains you use.由于您管理多个域,我建议您为所有使用的域使用一个站点密钥 Use secure token for that.为此使用安全令牌

Hack黑客

Another option might be that you develop a script that will visit site(s) of interest, make screenshot/snap of loaded reCaptcha, apply OCR (eg. using this ) and return a result if site key is valid or not.另一种选择可能是您开发一个脚本来访问感兴趣的站点,对加载的 reCaptcha 进行屏幕截图/快照,应用 OCR(例如,使用this )并在站点密钥有效与否时返回结果。

As Google does not provide an official way to check this, I've just implemented a workaround performing a GET request on Google's Recaptcha URL.由于谷歌没有提供官方方法来检查这一点,我刚刚实施了一种解决方法,在谷歌的 Recaptcha URL 上执行GET请求。 I've made using PHP, but it's not hard to adapt the solution for JavaScript, although it can end on a Cross-Origin error due to Same Origin Policy .我已经使用 PHP 进行了制作,但是为 JavaScript 调整解决方案并不难,尽管由于Same Origin Policy 可能会导致跨源错误。 So if someone tests this solution using JavaScript, let us know how it goes (and if it does not work, it's always possible to run an AJAX to your own server and check the validity directly from your server).因此,如果有人使用 JavaScript 测试此解决方案,请告诉我们它的运行情况(如果它不起作用,始终可以在您自己的服务器上运行 AJAX 并直接从您的服务器检查有效性)。

Besides that, in my case, I'm using Invisible ReCaptcha v2, but I think this approach can be used for other Recaptchas as well.除此之外,就我而言,我使用的是 Invisible ReCaptcha v2,但我认为这种方法也可用于其他 Recaptcha。

  1. First, you should mount your URL.首先,您应该挂载您的 URL。 I couldn't find a way to determine this "co" param, and I don't know what it means.我找不到确定这个“co”参数的方法,我不知道这意味着什么。 But it looks like different values are all accepted on different sites.但看起来不同的网站都接受了不同的值。 You can look for this value by adding the Recaptcha code on your page (no matter if it's with valid keys or not) and then checking the src param on the generated <iframe> .您可以通过在页面上添加 Recaptcha 代码(无论它是否具有有效密钥)来查找此值,然后检查生成的<iframe>上的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'
        );

on JavaScript it would be something like this:在 JavaScript 上,它会是这样的:

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

If you are not using Invisible Recaptcha, the size param must be different.如果您不使用 Invisible Recaptcha,则size参数必须不同。 But you can also omit it because, at least in my testing, it was not necessary for checking if the Site Key is valid (the same for the language param hl ).但是您也可以省略它,因为至少在我的测试中,没有必要检查站点密钥是否有效(语言参数hl )。

  1. Then, you perform a GET request on this URL.然后,您对该 URL 执行 GET 请求。 On PHP, you can use cURL .在 PHP 上,您可以使用cURL If it's Wordpress, you can use wp_remote_get .如果是 Wordpress,则可以使用wp_remote_get On JavaScript (jQuery, actually), you can use $.get .在 JavaScript(实际上是 jQuery)上,您可以使用$.get
    $.get( recaptcha_url, function(data, status){ ... });
  1. Finally, you check if the response body has the string 'Recaptcha.anchor.ErrorMain.init' .最后,您检查响应正文是否包含字符串'Recaptcha.anchor.ErrorMain.init' This means when the Recaptcha Site Key is not valid for the current domain, Google processes the error, and this string appears on the response body (actually, any ReCaptcha error would result on this string, so remember this is a workaround).这意味着当 Recaptcha 站点密钥对当前域无效时,Google 会处理错误,并且此字符串会出现在响应正文中(实际上,此字符串会导致任何 ReCaptcha 错误,因此请记住这是一种解决方法)。

If you are using Wordpress, you can do it with wp_remote_retrieve_body .如果您使用的是 Wordpress,则可以使用wp_remote_retrieve_body Something like this:像这样的东西:

    $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
    }

On JavaScript, I think you can check the data variable received on $.get .在 JavaScript 上,我认为您可以检查$.get上收到的data变量。

Unfortunately, this is not a strong solution.不幸的是,这不是一个强有力的解决方案。 Google can change both the request and the response, and this could break the implementation. Google 可以更改请求和响应,这可能会破坏实现。 But there is nothing we can do about it as there isn't an official call to check the keys.但是我们无能为力,因为没有官方电话来检查钥匙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM