One of the most annoying things of having a form in a website is seeing it being targeted by spam bots. In this article I'm going to explain how to get rid of them (or at least most of them...) by integrating Google's reCaptcha in our form.


Note: For this example I'll be using a Laravel app but I'll explain the basic concepts of how reCaptcha works and how to integrate it so, if you're using a different framework, you should be able to follow along.


We'll just need to follow a few simple steps:

  • Register your site in reCaptcha and get your site and secret keys.
  • Add the keys to the environment of our app (.env file in Laravel).
  • Include the reCaptcha input in our page form.
  • Add the reCaptcha validation in our back end (a controller method in Laravel).

Register your website

Registering your website to use reCaptcha is pretty straight forward. Just visit this link (logged in with your Google account) and fill the form. For the label, put something that will easily identify your site and for the reCaptcha type, I selected the v2 Checkbox (note that the integration is different depending on the type).

Once registered you'll get a screen with your unique keys and the client/server integration details:

keys

And that's all we have to do from the reCaptcha side. Now we just have to integrate it into our application.

Add keys to your app

We'd need to use our client and server keys to call the reCaptcha API from both the front and back end of our application so in order to have them available in our whole app, we can add the as environment variables or, as my app is built in Laravel, I'll use the .env file adding them at the end of it:

// .env file
GOOGLE_RECAPTCHA_KEY=YOUR_RECAPTCHA_SITE_KEY
GOOGLE_RECAPTCHA_SECRET=YOUR_RECAPTCHA_SECRET_KEY

In JavaScript you can load them as environment variables and access them with process.env.VARIABLE_NAME.

Include reCaptcha input in the form

Next step is to include the reCaptcha checkbox in our form using the two code snippets from the reCaptcha dashboard. For this example I have a contact form with a few inputs (name, email and text) that sends all the payload via a POST request to a route called "contact.send" which is handled by a controller. It looks like this:

The scripts provided in the reCaptcha dashboard contain the input that we'll have to add to our form, and the script that is executed when it's triggered. Here's how our previous form looks after I've added the snippets:

Note that the input snippet provided includes our site key hardcoded into it and, as I've included it in the .env file, I've replaced it with a reference to the variable ;) At this point we should be able to see the reCaptcha input when we load our form, but there is an additional step we need to do before it actually works.

Add reCaptcha validation back end

In order to understand the changes that we need to do in our controller, we first need to understand what actually happens when a user clicks on the reCaptcha input.

  • A request is sent to the Google servers in order to do the verification. This requests contains our site key so the verification is linked to our site.
  • Google server responds with  a unique id, which is included in our form in an input with the name "g-recaptcha-response". Once the form is submitted, we'll be able to access the "g-recaptcha-response" to obtain the verification id.

As part of the server side normal validations in our controller (check that all fields of our form are filled and with the correct format etc...) we'll need to also check if Google has successfully verified that our user is not a bot by sending a POST request to Google's /recaptcha/api/siteverify including our secret key and the verification id from the "g-recaptcha-response" input, as indicated in the reCaptcha documentation:

reCaptcha server integration

In PHP we can do this using the file_get_contents() function to send the POST request, and the json_decode() function to parse the response to a JSON object as follows:

In JavaScript, you can use axios to send the POST request and then JSON.parse() to transform the response to an object.

The response from our POST request will contain a "success" property with a true/false value which we'll use to return an error message or, as in this example, store the message in our database. Now it should be ready to test.

Conclusion

For me, adding reCaptcha to the public forms of the websites has become a must if you dont want to have to deal with tons of spam and bots. This article only covers the reCaptcha v2 checkbox, but different types can be integrated in a similar manner. Hope you find this article helpful :)

Happy coding!