DEV Community

Cover image for How to integrate Google ReCaptcha v3 correctly in 2022?
Ajay Kumar Verma
Ajay Kumar Verma

Posted on • Originally published at weekendtutorial.com

How to integrate Google ReCaptcha v3 correctly in 2022?

A solution to prevent email spamming.

Google Recaptcha is one of the industry-standard methods that solve the email spamming problem.

What is Email Spamming?

Email spam a.k.a junk emails refers to uninvited emails, usually sent to a large list of recipient email users. This recipient’s email addresses are stolen or purchased by attackers for money theft or commercial purpose depending on what attackers want.

These emails most of the time have hidden malware that was not supposed to open and if someone opens their mail and clicks the links will become a victim of these attackers.

e.g.

the places which is the source of the email spam –

  1. Login, signup and reset password forms on the site
  2. Comment and contact us section in a blog

There are 4 types of Google ReCaptcha

Google Recaptcha

In this article, we are going to integrate the google ReCaptcha v3 which is the latest.

If you’re already using Google Recaptcha v2 and you want to move to Google Recaptcha v3, you can read the Google documentation for the same, it is pretty straightforward.


Steps to Integrate Google Recaptcha V3

Step 1. Register your website on recaptcha admin

First of all, we need to register the website on the ReCaptcha admin console.

It looks like this –

Recpatcha Dashboard


Step 2. Client-Side Integration

After registering the website on the admin console, note down the reCAPTCHA keys.

e.g.

In the above image, you must be seeing the reCaptcha Keys.

ReCaptcha gives 2 keys –

  1. Site Key – this is the public key and is used in client-side integration.
  2. Secret Key – this is the private key and can’t be exposed to anyone. This should be safely stored in your backend server.

Let’s start with the client-side integration

1. Load the JavaScript API with your site key

<script src="https://www.google.com/recaptcha/api.js?render=<site_key>"></script>
Enter fullscreen mode Exit fullscreen mode

in the above, you will pass the actual Recaptcha Site Key in the place of <site_key>

e.g if the Recaptcha Site Key is sdfjhjk124jkhk

you will pass it as ?render=sdfjhjk124jkhk

2. Call grecaptcha.execute on each action you wish to protect

<script>
    function onClick(e) {
        e.preventDefault();
        grecaptcha.ready(function() {
            grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'}).then(function(token) {
                // Add your logic to submit to your backend server here.
            });
        });
    }
</script>
Enter fullscreen mode Exit fullscreen mode

Whichever input box you wish to protect, it could be your signup, login or some other field, you need to update the click handler for that, similar to above.

You can see the above code, we pass the actual Recaptcha site key and one callback function to the grecaptcha.execute function.

When the callback is executed, we get the token in it. And this token immediately needs to be passed to the backend server for fetching the user score.

3. Send the token immediately to your backend with the request to verify

This will trigger the server-side flow.


Step 3. Server-Side Integration

With the token passed by the client and with the Recaptcha Secret Key that was already stored at the server-side, the backend will make the call to google site-verify api.

The google site-verify API returns a score that is between 0.0 to 1.0. We also set one threshold score default of 0.5 up to which score we will allow users to make requests.

If the score is less than the threshold score we can say that the user is not human and it’s a bot. 
Enter fullscreen mode Exit fullscreen mode
If the score is >threshold score then the user is human and the actual functionality of click is allowed.
Enter fullscreen mode Exit fullscreen mode

Request end point

Request end point

Site Verify Response

The response is a JSON object.

Response


Challenge

On StackOverflow, I was searching for something and found out most of the people are implementing it incorrectly.

They are getting the score from server-side and comparing the score and threshold on the client-side which is completely wrong.

e.g. Below implementation is wrong

<script>
    function onClick(e) {
        e.preventDefault();
        grecaptcha.ready(function() {
            grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'}).then(function(token) {
                var score = fetchScoreFromAPI(token);
                if (score > THRESHOLD_SCORE) {
                    callCommentApi();
                }
            });
        });
    }
</script>
Enter fullscreen mode Exit fullscreen mode

The above is incorrect due to –

  1. the client never does the validation
  2. Attackers can easily manipulate the score and see the comment API endpoint and flood it with unsolicited emails.

Here is the correct implementation –

<script>
    function onClick(e) {
        e.preventDefault();
        grecaptcha.ready(function() {
            grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'}).then(function(token) {
                callCommentAPI(token);
            });
        });
    }
</script>

// At server side
function callCommentAPI(token){
    var score = fetchScoreFromAPI(token);
    if (score > THRESHOLD_SCORE) {
        // execute logic for comment API
    }
}
Enter fullscreen mode Exit fullscreen mode

So, we have just passed the token to the existing API and the validation is done at the server-side which is the more secure and correct way of doing it.

Also, you can notice that even if the comment API URL is exposed to the public but it won’t get spammed as it first checks the score.


Summary

I hope you have learned something new. Let me know if you think you can solve it differently or if something is wrong with the article.

Please read my other popular articles –

Nginx Tutorial
Browser Storage

That’s all for now, let’s meet next time soon.

Discussion (0)