简体   繁体   中英

How can I implement Google Recaptcha v3 in a PHP form?

I would like to insert a contact form the new version (V3) of Recaptcha.

I have looked for different solutions, but they only show part of the code, they are incomplete or I get an error, and most of the solutions found are very complicated for something so simple and I do not understand the code.

I have searched this and other forums to implement the new version of ReCaptcha (V3) in my forms. I needed to know how to:

  • Insert it with JS
  • How to validate it with PHP
  • What new fields were needed in my form.

I did not find any simple solution, which would show me all these points, or it was too complicated for somebody who just wanted to insert a contact form on their website.

At the end, taking some code portions of multiple solutions, I use a simple and reusable code, in which you only have to insert the corresponding keys.

Here it is.

The basic JS code

<script src="https://www.google.com/recaptcha/api.js?render=your reCAPTCHA site key here"></script>
<script>
    grecaptcha.ready(function() {
    // do request for recaptcha token
    // response is promise with passed token
        grecaptcha.execute('your reCAPTCHA site key here', {action:'validate_captcha'})
                  .then(function(token) {
            // add token value to form
            document.getElementById('g-recaptcha-response').value = token;
        });
    });
</script>

The basic HTML code

<form id="form_id" method="post" action="your_action.php">
    <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
    <input type="hidden" name="action" value="validate_captcha">
    .... your fields
</form>

The basic PHP code

    if(isset($_POST['g-recaptcha-response'])){
        $captcha=$_POST['g-recaptcha-response'];
    }
    else
        $captcha = false;

    if(!$captcha){
        //Do something with error
    }
    else{
        $secret = 'Your secret key here';
        $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']));
        if($response->{'success'}==false)
        {
            //Do something with error
        }
    }
    
   //... The Captcha is valid you can continue with the rest of your code
  //... Add code to filter access using $response . score
    if ($response->{'success'}==true && $response->{'score'} <= 0.5) {
        //Do something to denied access
    }

You have to filter access using the value of $response->{'score'}. It can takes values from 0.0 to 1.0, where 1.0 means the best user interaction with your site and 0.0 the worst interaction (like a bot). You can see some examples of use in ReCaptcha documentation .

You only have to add your keys, no more changes needed:

    src="https://www.google.com/recaptcha/api.js?render=your reCAPTCHA site key here"    
    grecaptcha.execute('your reCAPTCHA site key here'

and

    $secret = 'Your secret key here';

Obviously you also have to change the action of the form, in this example:

    action = "your_action.php"

In the answer above, these lines need to be updated in order to be able to read the response values in PHP:

    $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']));

    $response->{'success'}

    $response->{'score'}

Looks like Google improved their docs since the first answers. Here is how I do it.

Client side integration in form:

The docs for this are here: https://developers.google.com/recaptcha/docs/v3

According to Google you should include the Recaptcha API on every page so that it can observe the user's behavior. So I added this line to the end of my footer which is included in every page (no parameters needed):

<script src="https://www.google.com/recaptcha/api.js"></script>

On the form you use a submit button like so:

<button class="g-recaptcha" data-sitekey="PASTE-YOUR-RECAPTCHA-SITE-KEY-HERE" data-callback="onSubmit" data-action="submit">Submit Form</button>

And add the following JavaScript function that submits the form:

function onSubmit() {
    var form = document.forms[0]; // change this if you have multiple forms

    if (/* possible client-side form validation code here */) {
        form.submit();
    }
}

Server side validating code:

The docs for this are here: https://developers.google.com/recaptcha/docs/verify

For this I created a helper function:

/**
 * Checks if the current script has a valid Google Captcha response token.
 * @returns True, if the script has a valid repsonse token, otherwise false.
 */
function isCaptchaValid()
{
    $captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : false;

    if (!$captcha) {
        return false;
    }

    $postdata = http_build_query(
        array(
            "secret" => "PASTE-YOUR-RECAPTCHA-SECRET-KEY-HERE",
            "response" => $captcha,
            "remoteip" => $_SERVER["REMOTE_ADDR"]
        )
    );
    $opts = array(
        'http' =>
        array(
            "method"  => "POST",
            "header"  => "Content-Type: application/x-www-form-urlencoded",
            "content" => $postdata
        )
    );
    $context  = stream_context_create($opts);
    $googleApiResponse = file_get_contents("https://www.google.com/recaptcha/api/siteverify", false, $context);

    if ($googleApiResponse === false) {
        return false;
    }

    $googleApiResponseObject = json_decode($googleApiResponse);

    return $googleApiResponseObject->success;
}

No need to check any score value as done in the other answers. According to the docs there isn't even a score property in the response object. I checked it and there is one, but I don't use it.

You should call it at the beginning of the PHP script that handles your form submit like so:

if (!isCaptchaValid()) {
    die("STOP! You are a bot."); // or do something else
}

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