Skip to content

Instantly share code, notes, and snippets.

@reanim8ed
Created November 27, 2020 08:18
Show Gist options
  • Save reanim8ed/0a812da9f3288974a6cffd6ba74185f5 to your computer and use it in GitHub Desktop.
Save reanim8ed/0a812da9f3288974a6cffd6ba74185f5 to your computer and use it in GitHub Desktop.
[reCAPTCHA v3 validation] #php #recaptcha #validation #curl

Header:

  • Insert token to all .recaptcha_response elements on page ant refresh them every 2min
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_RECAPTCHA_SITE_KEY"></script>
<script>
$(document).ready(function () {
    var elements = document.getElementsByClassName('recaptcha_response');
    if (elements) {
        grecaptcha.ready(function () {
            grecaptcha_execute(elements);
        });
        setInterval(function () {
            grecaptcha_execute(elements)
        }, 120000);
    }
});

function grecaptcha_execute(elements){
    grecaptcha.execute('YOUR_RECAPTCHA_SITE_KEY', { action: 'form' }).then(function (token) {
        Array.from(elements).map(
            (element) => {
                return element.value=token;
            }
        );
    });
}
</script>

Form:

<input type="hidden" clas="recaptcha_response" name="recaptcha_response">

PHP:

/**
 * @param string|null $token
 * @return bool
 */
public static function validateToken(string $token = null): bool
{
    if (empty($token)) {
        return false;
    }

    $verifyURL = 'https://www.google.com/recaptcha/api/siteverify';

    $query_data = [
        'secret' => '6Leon-IZAAAAAAclFEsBURFcDdGM8RuFMpE12av5',
        'response' => $token,
        'remoteip' => (isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER['REMOTE_ADDR'])
    ];

    // Collect and build POST data
    $post_data = http_build_query($query_data, '', '&');

    try {
        // Send data on the best possible way
        if (function_exists('curl_init') && function_exists('curl_setopt') && function_exists('curl_exec')) {
            // Use cURL to get data much faster than using file_get_contents
            $ch = curl_init($verifyURL);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
            curl_setopt($ch, CURLOPT_TIMEOUT, 5);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-type: application/x-www-form-urlencoded'));
            $response = curl_exec($ch);
            curl_close($ch);
        } else {
            // If server doesnt have cURL - use file_get_contents
            $options = [
                'http' => [
                    'header'  => "Content-type: application/x-www-form-urlencoded",
                    'method'  => 'POST',
                    'content' => $post_data
                ]
            ];
            $context = stream_context_create($options);
            $response = file_get_contents($verifyURL, false, $context);
        }
    } catch (Exception $e) {
        return false;
    }

    // Verify validity
    if($response) {
        $result = json_decode($response);
        return isset($result->success) && $result->success === true && $result->score >= 0.5;
    }

    // Dead end
    return false;
}

Response example:

<?php
(
    [success] => 1
    [challenge_ts] => 2018-11-01T22:31:14Z
    [hostname] => recaptcha.local
    [score] => 0.9
    [action] => contact
)
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment