How can I use reCAPTCHA v2 on a large number of domains?

*爱你&永不变心* 提交于 2019-12-01 05:25:27
Aaron Cicali

It is possible to implement reCAPTCHA Version 2.0 without verifying each domain: https://developers.google.com/recaptcha/docs/domain_validation

To do so, visit the admin console and click the API key in question under "Your reCAPTCHA Sites". Then under "Advanced Settings", uncheck "Verify the origin of reCAPTCHA solutions".


Security Warning

Per Google, doing this creates a security risk that then requires you to check the hostname yourself.

Turning off this protection by itself poses a large security risk - your key could be taken and used by anyone, as there are no restrictions as to the site it's on. For this reason, when verifying a solution, you are required to check the hostname field and reject any solutions that are coming from unexpected sources.


Related Link: (from "Stack Exchange Information Security")
- Why bother validating the hostname for a Google Recaptcha response?

NOTE: This applies to a previous version of the reCAPTCHA API. See the other answer for an updated solution.


This doesn't seem to be well-known, but reCAPTCHA's documentation mentions that a Secure Token can be used to have one key working on a large number of domains. This feature seems to be exactly designed for this type of situation.

It's created by encrypting a JSON string with your site secret, but the documentation doesn't say exactly what encryption method to use. Here's some PHP code I've used to get it working in one of my projects. This should help with whatever language you're working with.

$token = json_encode(array(
    'session_id' => bin2hex(openssl_random_pseudo_bytes(16)), // Random ID; no special format
    'ts_ms' => intval(round(microtime(true) * 1000))) // Time in milliseconds
);

$secret_key = '{reCAPTCHA secret key}';
$secret_key_hash = substr(hash('sha1', $secret_key, true), 0, 16);

$stoken_bin = openssl_encrypt(
    $token,
    'AES-128-ECB', // Encryption method
    $secret_key_hash,
    OPENSSL_RAW_DATA // Give me the raw binary
);

// URL-safe Base64 encode; change + to -, / to _, and remove =
$stoken = strtr(base64_encode($stoken_bin), array('+'=>'-', '/'=>'_', '='=>''));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!