简体   繁体   中英

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. I'm using the explicit rendering mode and calling the api function 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. Is there anyway to detect an invalid site key automatically, either via javascript or server side?

Edit Final solution was to load a test page with phantomjs and parse the html of the recaptcha

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.

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.

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. 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 . 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).

Besides that, in my case, I'm using Invisible ReCaptcha v2, but I think this approach can be used for other Recaptchas as well.

  1. First, you should mount your URL. I couldn't find a way to determine this "co" param, and I don't know what it means. 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_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:

    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. 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 ).

  1. Then, you perform a GET request on this URL. On PHP, you can use cURL . If it's Wordpress, you can use wp_remote_get . On JavaScript (jQuery, actually), you can use $.get .
    $.get( recaptcha_url, function(data, status){ ... });
  1. Finally, you check if the response body has the string '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).

If you are using Wordpress, you can do it with 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 .

Unfortunately, this is not a strong solution. Google can change both the request and the response, and this could break the implementation. But there is nothing we can do about it as there isn't an official call to check the keys.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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