The Importance of reCAPTCHA in Modern Applications
In the digital age, safeguarding applications from bots and automated attacks is more critical than ever. Google’s reCAPTCHA provides a robust solution by verifying user authenticity, effectively preventing spam and protecting against brute force login attempts.
Modern reCAPTCHA versions are also much more user-friendly. Unlike older captchas that made users decipher distorted text, newer versions work silently in the background, allowing smoother user interactions while still providing strong protection.
To integrate reCAPTCHA, you need two keys: a site key and a secret key. The site key is used on the front end to display the reCAPTCHA widget, while the secret key is required on the backend to validate the token generated on frontend after user interaction.
When a user submits a form, a token will be created and sent to your backend endpoint, which communicates with Google’s API to verify the token. If the token is valid, the backend returns a confirmation (e.g., “OK”). We’ll handle only the frontend operations using the existing backend API.
vue-recaptcha-v3 is a Vue library that facilitates the integration of Google’s reCAPTCHA v3 into Vue.js applications. It enhances security by running in the background to score user interactions, effectively distinguishing between humans and bots without disrupting the user experience.
Implementing vue-recaptcha-v3 in Your Vue.js Application
Integrating vue-recaptcha-v3 into your Vue.js application involves a few straightforward steps. Here’s a guide to help you set it up, with a special focus on Nuxt.js.
Step 1: Install the Library
First, you need to install the vue-recaptcha-v3 package. Run one of the following commands in your project directory:
npm install vue-recaptcha-v3
yarn add vue-recaptcha-v3
Step 2: Obtain reCAPTCHA API Keys
Click and visit the Google reCAPTCHA admin console to register your site. You’ll receive two keys: Site Key & Secret Key. Make sure to choose reCAPTCHA v3 during registration. We will be using Site Key in the front-end.
Step 3: Create a Plugin
Next, create a new plugin file for reCAPTCHA. You can do this by creating a vue-recaptcha-v3.js file in the plugins directory:
*plugins/vue-recaptcha-v3.js*
import { defineNuxtPlugin } from '#app';
import { VueReCaptcha } from 'vue-recaptcha-v3';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueReCaptcha, {
siteKey: 'YOUR_SITE_KEY', // Replace with your site key
loaderOptions: {
autoHideBadge: true, // Optional: Automatically hides the badge
explicitRenderParameters: {
//badge: 'bottomleft', //incase you don't want to hide it
}
}
});
});
Badge Appearance
The reCAPTCHA badge is visible by default on all pages, but you can customize its behavior. For instance, you can choose to hide it by enabling the autoHideBadge option.
Customizing Badge Location
You can specify the position of the reCAPTCHA badge by using the loaderOptions when configuring vue-recaptcha-v3. Here are the available badge positions:
inline: The badge is shown inline (no fixed position).
bottomright: The badge appears in the bottom-right corner of the page.
bottomleft: The badge appears in the bottom-left corner of the page.
topright: The badge appears in the top-right corner of the page.
topleft: The badge appears in the top-left corner of the page.
Step 4: Register the Plugin
Add the plugin to the plugins array in your nuxt.config.js. Here’s an example configuration,
export default defineNuxtConfig({
devtools: { enabled: true },
//..
plugins:[
{src: '~/plugins/vue-recaptcha-v3.js', mode: 'client' },
],
..//
})
Now we can apply it in form…
Let’s break down the implementation of reCAPTCHA in your ContactForm component step by step.
Step 1: Setup and Import
First, we import the necessary modules from vue-recaptcha-v3 and define our component:
/ContactForm.vue
<script>
import { VueReCaptcha, useReCaptcha } from "vue-recaptcha-v3";
export default {
name: "ContactForm",
data() {
return {
form: {
name: "",
},
submissionMessage: null,
errorMessage: null,
};
},
setup() {
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
const recaptcha = async () => {
await recaptchaLoaded(); // Wait for reCAPTCHA to load
return await executeRecaptcha("contact"); // Create a reCAPTCHA token
};
return {
recaptcha,
};
},
The component imports VueReCaptcha and the useReCaptcha hook to manage reCAPTCHA.
The form object contains the user's input fields, while submissionMessage and errorMessage are used to display feedback.
Step 2: Token Creation
Next, we define the submitForm method to handle form submissions:
methods: {
async submitForm() {
const token = await this.recaptcha(); // Call the recaptcha method to get the token
console.log(token);
// Check if the token is valid
if (!token) {
this.errorMessage = "Invalid reCAPTCHA. Please try again.";
this.submissionMessage = null; // Clear previous messages
alert(this.errorMessage);
return; // Exit if the token is invalid
}
The recaptcha method is called to generate a token, which is logged to the console.
If the token is not generated (invalid), an error message is displayed, and the function exits early.
Step 3: CAPTCHA Validation
Once a valid token is created, the next step is to validate it:
try {
// Send the token to the CAPTCHA validation API first
const captchaResponse = await fetch(
"https://api.x.com/api/captcha",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ recaptcha_token: token }),
}
);
// If the CAPTCHA validation is successful (status 200), submit the form
if (captchaResponse.ok) {
console.log("response is ok");
The token is sent to your backend CAPTCHA validation endpoint using a POST request.
If the response is OK (status 200), it proceeds to prepare the form submission.
Step 4: Form Submission
If the CAPTCHA validation passes, the form data is sent:
const formData = new FormData();
formData.append("name", this.form.name);
formData.append("recaptchaToken", token);
const formSubmitResponse = await fetch(
"https://api.x.com/api/contact",
{
method: "POST",
body: formData,
}
);
// Check if the form submission response is okay (status 200-299)
if (formSubmitResponse.ok) {
const result = await formSubmitResponse.json();
this.submissionMessage = "Contact form submitted successfully!";
alert(this.submissionMessage); // Show success alert
A FormData object is created to hold the form inputs, including the reCAPTCHA token. The form data is sent to your form submission endpoint. If the submission is successful, a success message is displayed.
Step 5: Error Handling
If either the CAPTCHA validation or form submission fails, appropriate error messages are shown:
} else {
const error = await formSubmitResponse.json();
this.errorMessage = error.message || "Error submitting form.";
alert(this.errorMessage);
this.submissionMessage = null; // Clear previous messages
}
} else {
this.errorMessage = "CAPTCHA validation failed. Please try again.";
alert(this.errorMessage);
this.submissionMessage = null;
}
} catch (error) {
console.error("Submission error:", error);
this.errorMessage = "An error occurred while submitting the form.";
this.submissionMessage = null; // Clear previous messages
alert(this.errorMessage); // Show error alert
}
Error Handling: If there are issues with the CAPTCHA validation or form submission, the error messages are displayed, allowing users to understand what went wrong.
Step 6: Resetting the Form
Finally, the form can be reset after submission:
resetForm() {
this.form.name = "";
},
Here’s the complete code for the ContactForm component, integrating reCAPTCHA for secure form submissions:
/ContactForm.vue
<script>
import { VueReCaptcha, useReCaptcha } from "vue-recaptcha-v3";
export default {
name: "ContactForm",
data() {
return {
form: {
name: "",
},
submissionMessage: null,
errorMessage: null,
};
},
setup() {
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
const recaptcha = async () => {
await recaptchaLoaded(); // Wait for reCAPTCHA to load
return await executeRecaptcha("contact"); // Create a reCAPTCHA token
};
return {
recaptcha,
};
},
methods: {
async submitForm() {
const token = await this.recaptcha(); // Call the recaptcha method to get the token
console.log(token);
// Check if the token is valid
if (!token) {
this.errorMessage = "Invalid reCAPTCHA. Please try again.";
this.submissionMessage = null; // Clear previous messages
alert(this.errorMessage);
return;
}
try {
// Send the token to the CAPTCHA validation API first
const captchaResponse = await fetch(
"https://api.x.com/api/captcha",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ recaptcha_token: token }),
}
);
// If the CAPTCHA validation is successful (status 200), submit the form
if (captchaResponse.ok) {
console.log("response is ok");
// Prepare form data for submission
const formData = new FormData();
formData.append("name", this.form.name);
formData.append("recaptchaToken", token); // Append the reCAPTCHA token
// Submit the form data
const formSubmitResponse = await fetch(
"https://api.x./api/contact",
{
method: "POST",
body: formData,
}
);
// Check if the form submission response is okay (status 200-299)
if (formSubmitResponse.ok) {
const result = await formSubmitResponse.json();
this.submissionMessage = "Contact form submitted successfully!";
this.errorMessage = null; // Clear previous error messages
alert(this.submissionMessage); // Show success alert
} else {
// Handle errors from the form submission server
const error = await formSubmitResponse.json();
this.errorMessage = error.message || "Error submitting form.";
alert(this.errorMessage);
this.submissionMessage = null; // Clear previous messages
}
} else {
// Handle CAPTCHA validation error
this.errorMessage = "CAPTCHA validation failed. Please try again.";
alert(this.errorMessage);
this.submissionMessage = null;
}
} catch (error) {
console.error("Submission error:", error);
this.errorMessage = "An error occurred while submitting the form.";
this.submissionMessage = null; // Clear previous messages
alert(this.errorMessage); // Show error alert
}
},
resetForm() {
this.form.name = "";
},
},
beforeUnmount() {
this.$recaptcha.destroy();
},
};
</script>
" Please note that reCAPTCHA may not function correctly on localhost. It's recommended to test it in a deployed environment. "
Conclusion
By implementing this step-by-step guide, you’ve successfully integrated reCAPTCHA into your form component. This not only enhances the security of your form submissions but also ensures a smooth and transparent user experience.
“Let’s hope the bots can’t outsmart this reCAPTCHA — if they do, I’ll need to write a new article to fool them! Until then, stay secure.”
See you in next article!
Elif Nur Türk
Top comments (0)