How to add Google ReCAPTCHA v3 to web form
12 July 2022
Prerequisites:
Within your admin section You'll have to create Google reCAPTCHA keys (site key and sercret key). Site key is necessary for client side implementation and secret key for server side validation. During creation process it's good practice to add your production domains and also localhost, so you'll be able to test on your dev/localhost environment.
After creation is done, you will have someting like this (not real data on screen):
SITE-KEY: 6LdqgOIgAAAAVD_0RPyK9Vtkqve4rpj5mR3Xg-ZQ
SECRET-KEY: 6LdqgOIgAAAACDKdvFp33snv6bHGuOAgZl0w4QQcd
Now, let's prepare our web form with necessary modifications.
HTML / Client side:
<!-- 1. Our form we need to protect against bots -->
<form action="/url-to-post" method="post" id="frm">
<label for="email">Your email:</label>
<input type="text" name="email" id="email" />
<button type="submit">Submit</button>
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
</form>
<!-- 2. Connect to Google API -->
<script src="https://www.google.com/recaptcha/api.js?render=SITE-KEY:"></script>
<!-- 3. Get token and populate our hidden filed with it, this token will be server side verified -->
<script>
grecaptcha.ready(function () {
grecaptcha.execute('SITE-KEY:', { action: 'contact' }).then(function (token) {
var recaptchaResponse = document.getElementById('recaptchaResponse');
recaptchaResponse.value = token;
});
});
</script>
Server side validation:
To perform server side validation, you'll need to pass your data within google's check URL:
https://www.google.com/recaptcha/api/siteverify
This can be done with any server side technology (PHP, C#, nodejs ...). PHP example:
$post_data = http_build_query(
array(
'secret' => '6LdqgOIgAAAACDKdvFp33snv6bHGuOAgZl0w4QQcd',
'response' => $_POST['recaptcha_response'],
'remoteip' => $_SERVER['REMOTE_ADDR']
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create($opts);
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);
$result = json_decode($response);
if (!$result->success) {
throw new Exception('Gah! CAPTCHA verification failed', 1);
}
$result
form example above is response JSON object with properties:
{
"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
}
As you can see, validation can be successful, but there is an extra property score
that describes result quality (0.0 - 1.0). Lower number === more likely a bot.
Bottom line, to be sure you are not dealing with bot, you need to get response with success
set to true and score
as higher as possible (I would go with score >= 0.5)