Google reCAPTCHA Enterprise: Integrate the “I’m not a robot” Challenge In Vue.js

Bat the Bot!
Nov 30 2023 · 4 min read

Background

With the rise of automated bots and malicious activities, it has become crucial for developers to implement robust security measures.

One such powerful tool that comes to the rescue is the reCAPTCHA integration, which forces the user who accesses an application to verify their identity.

Google has been defending millions of sites with reCAPTCHA for over a decade. reCAPTCHA Enterprise is built on the existing reCAPTCHA API and it uses advanced risk analysis techniques to distinguish between humans and bots.

In this blog, we will discuss how to integrate Google reCAPTCHA Enterprise with your website or web application to protect them against unwanted intrusions.

Let’s make our web application more secure from ever-persistent ‘bots’!

NOTE: we’re not going to use any npm package for recaptcha, instead we will go with the enterprise.js script.

Sponsored

We are what we repeatedly do. Excellence, then, is not an act, but a habit. Try out Justly and start building your habits today!
 

Prerequisites

  • A Google cloud project
  • A running vue.js project

Get ready with the above prerequisites if you’re not already.


Enable recaptcha API

Navigate to reCAPTCHA Enterprise and Enable the API.

Enable reCAPTCHA Enterprise API

If you’ve already enabled the API, you will see a screen like below.

2.webp

Consider referring to the Google guide, in case you want to know more.

 


Create reCAPTCHA Key

To create a reCAPTCHA key, navigate to the Create Key tab and Click the CREATE KEY button.

3.webp
Create a reCAPTCHA site key

Note: Make sure to enable the Use tick box challenges option, it’s can not be modified later.

You will be able to see the created site key as below.
 

4.webp
Created reCAPTCHA site key

Refer to more about it at How to create site key for reCAPTCHA Enterprise.


Render the checkbox challenge(I’m not a robot)

Let’s load the enterprise.js using the mounted hook.

App.vue

<script>
export default {
  mounted() {

    let recaptchaScript = document.createElement("script");
    recaptchaScript.setAttribute(
      "src",
      "https://www.google.com/recaptcha/enterprise.js?render=6LdjjyEpAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXO4"
    );
    recaptchaScript.setAttribute("async", "true");
    recaptchaScript.setAttribute("defer", "true");
    document.head.appendChild(recaptchaScript);
  }
}
</script>

<template>
  <div>reCAPTCHA Enterprise Demo</div>
</template>

When running the application, it shows a bad request error as below.

5.webp
reCAPTCHA render throws a Bad request error

It’s because we have appended the site key along with the script and that’s not expected for rendering the Checkbox challenge(I’m not a robot). However, it’s required for Invisible recaptcha integration.

The script should look like this,

recaptchaScript.setAttribute(
      "src",
      "https://www.google.com/recaptcha/enterprise.js"
    );

After removing the site key, the error is gone. It’s time to render the checkbox challenge now.

Let’s add the below code inside the mounted hook after the recaptcha enterprise script gets loaded.

grecaptcha.enterprise.render("recaptcha_container", {
        sitekey: "6LdjjyEpAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXO4",
        action: "verify",
        callback: (token) => {
          window.recaptcha_token = token;
        },
 });

Add the below <div> inside <template> with an id recaptcha_container , so that grecaptcha can identify it and render the challenge inside it.

<div id="recaptcha_container"></div>

You will see the browser shows an error like below.
 

6.webp
Error: grecaptcha is not defined

The error tells us that we want to use grecaptcha instance, but it’s not available yet. It’s because the script is not loaded yet completely.

The possible workaround is to access the grecaptcha instance only after the recaptcha enterprise script is loaded.

For that I have tried two solutions, but neither worked.
1. Loaded the recaptcha enterprise script synchronously(By removing async keyword)
2. Loaded the recaptcha enterprise script inside index.html — It works on running application without building it, but with build it doesn’t work always — sometime works sometime doesn’t!).
So, It’s not the ultimate solution😵, let’s take the bold move toward the right solution🚀.

Fix grecaptcha is not defined

  • We’re going to use the kind of promise thing — that’s listening to an onload event of enterprise.js.
  • It will make sure that when we access the grecaptcha instance the script is loaded before always, In case the script is not loaded it will not access the grecaptcha.enterprise.render() method anyway!

Attach an onload event with the recaptcha script and bind it with onloadCallback as below.

recaptchaScript.setAttribute(
      "src",
      "https://www.google.com/recaptcha/enterprise.js?onload=onloadCallback"
    );

Now, need to implement onloadCallback, which will manage the execution of grecaptcha.enterprise.render() method.

Caution— If you define onloadCallback inside methods property of the vue component, the script won’t find it as it loads at the window level whilst the methods are specific to Vue instance and are not accessible globally.

By considering the above caution, let’s define onloadCallback at window level.

window.onloadCallback = () => {
       grecaptcha.enterprise.render("recaptcha_container", {
        sitekey: "6LdjjyEpAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXO4",
        action: "verify",
        callback: (token) => {
          window.recaptcha_token = token;
          console.log("recaptcha token : ", token);
        },
      });
    };

Boom!! You will see the reCAPTCHA rendered when you run the application. When you click on the checkbox it will generate a token that you can pass to the backend if you want to verify on the backend side.

Generated recaptcha

Putting it all together…

<script>
export default {
  mounted() {

    window.onloadCallback = () => {
       grecaptcha.enterprise.render("recaptcha_container", {
        sitekey: "6LdjjyEpAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXO4",
        action: "verify",
        callback: (token) => {
          window.recaptcha_token = token;
          console.log("recaptcha token : ", token);
        },
      });
    };

    let recaptchaScript = document.createElement("script");
    recaptchaScript.setAttribute(
      "src",
      "https://www.google.com/recaptcha/enterprise.js?onload=onloadCallback"
    );
    recaptchaScript.setAttribute("async", "true");
    recaptchaScript.setAttribute("defer", "true");
    document.head.appendChild(recaptchaScript);
  }
}
</script>

<template>
  <div>reCAPTCHA Enterprise Demo</div>
  <div id="recaptcha_container"></div>
</template>

Verify the token using the Backend

To verify the reCAPTCHA token at the backend side, refer to How to Create Assessments for the Websites.

Last but not least, if you want to integrate an invisible reCAPTCHA in vue.js, have a look at How to integrate Invisible reCAPTCHA.


Similar Articles


nidhi-d image
Nidhi Davra
Web developer@canopas | Gravitated towards Web | Eager to assist


nidhi-d image
Nidhi Davra
Web developer@canopas | Gravitated towards Web | Eager to assist


Talk to an expert
get intouch
Our team is happy to answer your questions. Fill out the form and we’ll get back to you as soon as possible
footer
Subscribe Here!
Follow us on
2024 Canopas Software LLP. All rights reserved.