Google provides a very nice way to prevent spamming through any FORM that could be a contact form, registration form, etc. We are talking about Google ReCaptcha. ReCaptcha also helps to prevent automated data injection through scripting.
Table of content
Today we are going to learn how to implement Google reCaptcha on both client-side and the server-side. But before that, we need reCaptcha Site Key and the Secret Key. The Site key is used to implement the reCaptcha on the front end. And the secret key is used to authenticate the request.
Google reCaptcha Site Key and Secret key
The first step is to register your website to the google recaptcha site. Then you will see the screen like below.
Once you get the above screen, you need to add a unique label (You could use your website name). Next, select the reCaptcha version and the domain(s).
You can add as many domains as you want including the local development URL. Next, click on the save button and get the Site Key and the Secret Key.
Add reCaptcha to frontend
Adding Google reCaptcha on the client site is very easy. You need to add the script tag with google recaptcha API and a DOM element in your FORM with the site key.
<head>
....
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-12 my-5">
<form action="" method="POST">
<div class="form-group">
<label>Full Name</label>
<input type="text" name="full_name" class="form-control" placeholder="Enter full name">
</div>
<div class="form-group">
<label>Email address</label>
<input type="email" name="email" class="form-control" placeholder="Enter email">
</div>
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" class="form-control" placeholder="Enter subject">
</div>
<div class="form-group">
<label>Message</label>
<textarea name="message" class="form-control" rows="4" placeholder="Your Message"></textarea>
</div>
<div class="form-group">
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</body>
Now if you check the HTML Page and you will see the form like the below screen.
The reCaptcha will generate a new field that you can capture at server-side i.e. g-recaptcha-response
.
Validate Google reCaptcha with PHP
Time to move to the server-side to validate the google recaptcha. Please add the following script at the beginning because our first process is to authenticate the request.
if (isset($_POST['g-recaptcha-response'])) {
if (empty($_POST['g-recaptcha-response'])) {
echo "Please select the captcha.";
exit();
}
// Authenticate post request to server
$url = 'https://www.google.com/recaptcha/api/siteverify';
$captcha = $_POST['g-recaptcha-response'];
$data = array('secret' => 'your-secret-key', 'response' => $captcha);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$responseKeys = json_decode($response, true);
if (! $responseKeys["success"]) {
echo "Un-Authenticated Request.";
exit();
}
// Process the form below
.....
.....
}
In the above codes, we have used the file_get_contents()
to send the request and get the response. Alternatively, if you are familiar with the composer then we can use the google/recaptcha package and modify the code like below.
require_once '/path/to/recaptcha/src/autoload.php';
if (isset($_POST['g-recaptcha-response'])) {
if (empty($_POST['g-recaptcha-response'])) {
echo "Please select the captcha.";
exit();
}
$secret = 'your-secret-key';
$recaptcha = new \ReCaptcha\ReCaptcha($secret);
$resp = $recaptcha->setExpectedHostname('app.localhost')
->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
if ($resp->isSuccess()) {
// Verified!
// Process the form below
.....
.....
} else {
$errors = $resp->getErrorCodes();
}
}
Make sure to change the following line according to your setting domains.
$recaptcha->setExpectedHostname('app.localhost')