Fighting spam with reCAPTCHA

Update: As you know I try to avoid Google nowadays so you might want to look into Cloudflare Turnstile instead of Google’s reCAPTCHA.

I recently started adding Google’s reCAPTCHA to my sites. So far it has worked out very well! Until reCAPTCHA fighting spam seemed to be a never-ending war. Anyone who has used the internet has encountered it and anyone who runs any kind of internet service or website have loathed it.

reCaptcha Widget
reCAPTCHA Widget

Not only will spam ruin a user’s experience but unchecked spam on your website will cause Google, Bing, and other search engines to send your site into search oblivion never to be seen again. Even the biggest sites on the internet have problems with spam. Take Twitter for example, It is polluted with countless bot accounts. One spammer on Twitter can easily make themselves appear to be 1000 people. In my opinion spammers are the scum of the internet.

reCAPTCHA

I have managed to come up with several techniques over the years that I have used to defend against spam. Most have worked out well. Simple things like adding in an extra question to a PHPBB registration form so that the automatic bots leave it blank and fail the registration.

But for a high target site, the spammers simply adapt and then your back to square one. This endless cycle has worn on me and I am just tired of dealing with it. I am tired of going to all-out war with spam. I am tired of wasting my time cleaning up sites when I could instead be using that same time to improve the site and user experience. I am just tired of it all. So I have turned to reCAPTCHA.

What is reCAPTCHA

reCAPTCHA is Google’s CAPTCHA service that uses artificial intelligence and machine learning to detect spambots. So why not prevent spam with recaptcha and let the service do the hard work for you?

How to install reCAPTCHA on your forms.

Make an account

First, you need a reCAPTCHA account. You can use your Google account for this. Then you go to Google’s reCAPTCHA site and register the site that you are going to use reCAPTCHA on. The form should look something like this.

reCAPTCHA Register Site

At this point, you should get a Site key and a Secret key. Keep these close by because you will need them later.

Adding reCAPTCHA to a webpage.

This is the easy part. All you have to do is add the client-side code to the page you want CAPTCHA on.

Put this in the header or above were the CAPTCHA will be.

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

Then put this code where you want the reCAPTCHA widget to appear.

<div class="g-recaptcha" data-sitekey="SITE KEY HERE"></div>

That is about it with the web page side unless you want to get fancy with javascript. To do that add some callback funtions to check if the captcha has been finished or not.

<div class="g-recaptcha" data-sitekey="SITE KEY HERE" data-callback="recaptchaTrue" data-expired-callback="recaptchaFalse"></div>
Setting up reCAPTCHA in PHP

For the server side code I am using PHP. When a user submits a form with POST the google code adds an extra post variable called “g-recaptcha-response” that you need to capture. Here I am saving it to a variable called “recaptchaResponse”.

$recaptchaResponse = $_POST["g-recaptcha-response"];

Next we need to take the data in the “recaptchaResponse’ variable and send it back to Google in a POST so they can tell us if this form data comes from a verified user or if it is a spambot. To do this we need to send a new POST with PHP.

First we put all the POST data we are going to send into a php array, The API requires 3 things in the POST data. Your secret key so they know who you are. The recaptcha response we saved to a variable and the IP address of the computer that submited the form. I put all this into my PHP array like this.

$postdata = array('secret' => 'SECRET KEY HERE', 'response' => $recaptchaResponse, 'remoteip' => $_SERVER['REMOTE_ADDR']);

Next we add this data into another array that tells PHP how to send the post.

$options = array('http' =>
                 array(
                 'method' => 'POST',
                 'header' => 'Content-type: application/x-www-form-urlencoded',
                 'content' => http_build_query($postdata)
                 )
);
$context = stream_context_create($options);

Now we send the POST to google and save the response in a variable.

$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);

Google sends the response back as json. So we have to decode that into something we can use.

$result = json_decode($response);

Now that we have the response in a usable form we can test the results to see if the user passed or failed the reCAPTCHA test.

if ($result->success == true) //If user passes reCAPTCHA test.
{
        //Do Something
}
else
{
        //Do something
}
Putting it all together

Here is the full PHP code that handles reCAPTCHA from my “contact me” page.

$subject = $_POST["subject"];
$email = $_POST["email"];
$body = $_POST["body"];
//Start Captcha code
$recaptchaResponse = $_POST["g-recaptcha-response"];

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

$result = json_decode($response);

if ($result->success == true) //If user passes reCAPTCHA test.
{
        $recaptchaPass = true;
}
else
{
        $recaptchaPass = false;
}

//End Captcha code

Now I just stop or continue processing the form data based on the $recaptchaPass variable.

Leave a Reply

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