How to implement Google reCaptcha V3 in PHP

Google recently introduced reCAPTCHA V3, which is a pure Javascript API that requires no user interaction at all. Official documentation can be found here.

One major difference is that reCAPTCHA’s Site Verify Response now returns more information:

{
"success": true|false,      // whether this request was a valid reCAPTCHA token for your site
"score": number             // the score for this request (0.0 - 1.0)
"action": string            // the action name for this request (important to verify)
"challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
"hostname": string,         // the hostname of the site where the reCAPTCHA was solved
"error-codes": [...]        // optional
}

So in your verification code you can check for parameters like “success”, “score”, “action”, etc. The below is a very basic one-page demo on how to use reCaptcha V3 in a form.

Remember to replace “YOUR_SECRET_KEY” and “YOUR_SITE_KEY” with the keys obtained from https://www.google.com/recaptcha/admin

<?php
//function to verify captcha
function checkCaptcha(){    
    if(isset($_POST['captcha-response'])){
        $response = $_POST['captcha-response'];
 
        $postdata = http_build_query(
            array(
                'secret'   => 'YOUR_SECRET_KEY',
                'response' => $response,
                'remoteip' => $_SERVER['REMOTE_ADDR']
            )
        );
 
        $options = array('http' =>
            array(
                'method'  => 'POST',
                'header'  => 'Content-type: application/x-www-form-urlencoded',
                'content' => $postdata
            )
        );
 
        $context = stream_context_create($options);
        $result  = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context));
 
        //check if 'success' is ture, 'action' is the same as the one specified in your form and 'score' is greater than 0.5
        if($result->success && $result->action == 'yourActionName' && $result->score > 0.5){
            return true;
        }
    }
 
    return false;
}
 
//handle form post request
if(isset($_POST['name'])){
    $result = checkCaptcha();
 
    //success
    if($result){
        echo 'success';
    }
    //validation failed
    else{
        echo 'validation failed';
    }
}
?>
<!DOCTYPE html>
<html lang="en-AU">
<head>
    <title>reCaptcha V3 Demo</title>
</head>
<body>
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" id="your-form-id" method="post">
        <div>name: <input type="text" name="name" /></div>
        <div>email: <textarea name="enquiry_comment"></textarea></div>
        <div><button type="button" onclick="frmSubmit();">Submit</button></div>
        <input type="hidden" id="captcha-response" name="captcha-response" />
    </form>
    <script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
    <script>
    function frmSubmit(){
        grecaptcha.ready(function() {
            grecaptcha.execute('YOUR_SITE_KEY', {action: 'yourActionName'}).then(function(token) {
                document.getElementById("captcha-response").value = token;                
                document.getElementById("your-form-id").submit();
            });
        });
    }    
    </script>
</body>
</html>

One thought on “How to implement Google reCaptcha V3 in PHP”

  1. outstanding example and article, thank you so much. i wish i had seen ‘Submit’ early on, i missed the “frmSubmit()” part! i am using your excellent example to retrofit an existing php contact-page script.

    thought: maybe put the publicKey and privateKey as variables at the beginning of the script?

    thank you for providing such an excellent example that is easy to follow.

Leave a Reply

Your email address will not be published. Required fields are marked *