Validating Google reCAPTCHA
← ejemplos
This example is a step by step instruction on how to use a remote validator to verify a Google reCAPTCHA.
Registry keys
You need to register a public and private keys provided at Get reCAPTCHA page.
Showing the captcha
Assume that the captcha will be placed inside an element with id of
recaptcha
as following:
<form id="defaultForm" method="post" class="form-horizontal">
<div class="form-group">
<label class="col-sm-3 control-label">Captcha</label>
<div class="col-sm-9 captchaContainer">
<div id="recaptcha"></div>
</div>
</div>
</form>
Google reCAPTCHA allows using either Non-Javascript or Ajax API to show up the recaptcha image. In this example, we will use the reCAPTCHA Ajax API.
<!-- The reCAPTCHA Ajax script -->
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Call the FormValidation plugin
$('#defaultForm').formValidation({
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
}
// You can define other settings and other fields on form here
});
// Replace 'PUBLIC_KEY' with your public key
// The second parameter 'recaptcha' is the Id of element showing up the captcha image
Recaptcha.create('PUBLIC_KEY', 'recaptcha', {
theme: 'white'
});
});
</script>
reCAPTCHA then creates a text box with name of recaptcha_response_field
. We
use the addField() method to add this field:
<script type="text/javascript">
$(document).ready(function() {
$('#defaultForm').formValidation(...);
Recaptcha.create('PUBLIC_KEY', 'recaptcha', {
theme: 'white',
// captchaLoaded function will be called after the captcha image is loaded
callback: captchaLoaded
});
function captchaLoaded() {
// Add new field after loading captcha
$('#defaultForm').formValidation('addField', 'recaptcha_response_field', {
validators: {
notEmpty: {
message: 'The captcha is required and can\'t be empty'
}
}
});
};
});
</script>
At the moment, the captcha field uses only notEmpty validator indicating that the field is required. We will use the remote validator to verify it in the next step.
Currently, if you leave the captcha empty and submit the form, the field will be masked as invalid. But the element showing captcha seem to be shown not properly, because the feedback icon is placed right after the field:
In order to fix this, we need to move the feedback icon right after the
recaptcha
element. It can be done by triggering the added.field.fv event, which is called after adding a
field:
<script type="text/javascript">
$(document).ready(function() {
...
function captchaLoaded() {
$('#defaultForm')
.on('added.field.fv', function(e, data) {
// The field "recaptcha_response_field" has just been added
if (data.field === 'recaptcha_response_field') {
// Find the icon
var $icon = data.element.data('fv.icon');
// Move icon to other position
$icon.insertAfter('#recaptcha');
}
})
.formValidation('addField', 'recaptcha_response_field', {
validators: {
notEmpty: {
message: 'The captcha is required and can\'t be empty'
}
}
});
};
});
</script>
Now, try to submit the form, and you will see that the feedback icon is shown at the desired position:
Verifying the captcha
The last step is to validate the captcha using the remote validator. Google reCAPTCHA requires the value
of recaptcha_response_field
and recaptcha_challenge_field
fields. The last one is a hidden field generated by Google reCAPTCHA.
So, we need to send these fields to our back-end:
<script type="text/javascript">
$(document).ready(function() {
...
function captchaLoaded() {
$('#defaultForm')
.on('added.field.fv', function(e, data) {
...
})
.formValidation('addField', 'recaptcha_response_field', {
validators: {
notEmpty: {
message: 'The captcha is required and can\'t be empty'
},
remote: {
type: 'POST',
url: 'recaptcha.php',
message: 'The captcha is not valid',
data: function() {
// We also need to send the challenge field value
return {
recaptcha_challenge_field: $('#defaultForm').find('[name="recaptcha_challenge_field"]').val()
};
},
// Set it to enough time that you think the user complete typing the captcha
delay: 1000
}
}
});
};
});
</script>
Google reCAPTCHA provides many libraries in different languages to help us verify the
captcha based on recaptcha_response_field
and
recaptcha_challenge_field
values.
To simply demonstrate the back-end verifying process, I use the reCAPTCHA PHP library which can be downloaded here.
<?php
// Register the public and private keys at https://www.google.com/recaptcha/admin
define('PUBLIC_KEY', '...');
define('PRIVATE_KEY', '...');
// Download the PHP library
// https://developers.google.com/recaptcha/docs/php
require_once('recaptchalib.php');
// Verify the captcha
// https://developers.google.com/recaptcha/docs/verify
$resp = recaptcha_check_answer(PRIVATE_KEY,
$_SERVER['REMOTE_ADDR'],
$_POST['recaptcha_challenge_field'],
$_POST['recaptcha_response_field']
);
echo json_encode(array(
'valid' => $resp->is_valid,
));
Of course, you can use your own solution to verify the captcha as long as the back-end
need to return an encoded JSON containing the valid
key.
Final code
<form id="defaultForm" method="post" class="form-horizontal">
<div class="form-group">
<label class="col-xs-3 control-label">Captcha</label>
<div class="col-xs-9 captchaContainer">
<div id="recaptcha"></div>
</div>
</div>
</form>
<script src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script>
$(document).ready(function() {
$('#defaultForm').formValidation({
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
}
});
// Replace 'PUBLIC_KEY' with your public key
Recaptcha.create('PUBLIC_KEY', 'recaptcha', {
theme: 'white',
callback: captchaLoaded
});
function captchaLoaded() {
$('#defaultForm')
.on('added.field.fv', function(e, data) {
// The field 'recaptcha_response_field' has just been added
if (data.field === 'recaptcha_response_field') {
// Find the icon
var $icon = data.element.data('fv.icon');
// Move icon to other position
$icon.insertAfter('#recaptcha');
}
})
// Add new field after loading captcha
.formValidation('addField', 'recaptcha_response_field', {
validators: {
notEmpty: {
message: 'The captcha is required and can\'t be empty'
},
remote: {
type: 'POST',
url: 'recaptcha.php',
message: 'The captcha is not valid',
data: function() {
return {
recaptcha_challenge_field: $('#defaultForm').find('[name="recaptcha_challenge_field"]').val()
};
},
// Set it to enough time that you think the user complete typing the captcha
delay: 1000
}
}
});
};
});
</script>
<?php
// recaptcha.php
// Register the public and private keys at https://www.google.com/recaptcha/admin
define('PUBLIC_KEY', '...');
define('PRIVATE_KEY', '...');
// Download the PHP library
// https://developers.google.com/recaptcha/docs/php
require_once('recaptchalib.php');
// Verify the captcha
// https://developers.google.com/recaptcha/docs/verify
$resp = recaptcha_check_answer(PRIVATE_KEY,
$_SERVER['REMOTE_ADDR'],
$_POST['recaptcha_challenge_field'],
$_POST['recaptcha_response_field']
);
echo json_encode(array(
'valid' => $resp->is_valid,
));
The following image shows how the field looks like when the captcha is valid: