This article demonstrates two ways to validate a React form using Google's ReCaptcha and React simple captcha. The recommended way is to use Google's ReCaptcha; the easy way is to use the React simple captcha. If your form data contains sensitive information, consider using Google's ReCaptcha.
Steps to Implement React simple captcha Validation
Install Dependencies
We have to install the react-simple-captcha
library, which provides a React component for the captcha.
npm install react-simple-captcha
or
yarn add react-simple-captcha
Using Simple Captcha in a form
Here is how to use the simple captcha in a simple React Js form. Here I prevent bots from submitting the form. Therefore, the submit button appears after a successful captcha validation.
import { useEffect, useState } from "react"
import { LoadCanvasTemplate, loadCaptchaEnginge, validateCaptcha } from "react-simple-captcha"
export const SignupForm = () => {
const [error, setError] = useState('')
const [isFormValid, setIsFormValid] = useState(false)
const handleFormSubmit = (event) => {
event.preventDefault()
}
const validateFormUser = () => {
const captchaInput = document.getElementById('captcha_input').value
setError("")
if (validateCaptcha(captchaInput) === true) {
setIsFormValid(true)
} else {
setError("Invalid Captcha")
}
}
useEffect(() => {
loadCaptchaEnginge(6, 'green')
}, [])
return (
<>
<form onSubmit={handleFormSubmit}>
{error && <p>{error}</p>}
<label >
Name: <input type="text" name="name" />
</label>
<br />
<label>
Password: <input type="password" name="password" />
</label>
{isFormValid && <input type="submit" value="Submit" />}
</form>
{!isFormValid && <div>
<LoadCanvasTemplate />
<input type="text" id="captcha_input" />
<input type="button" value="Validate" onClick={validateFormUser} />
</div>}
</>
)
}
You may encounter a webpack
related error Module not found: Error: Can't resolve 'buffer'
. In such cases, installing buffer fixes the issue.
npm install --save buffer
Steps to Implement Google reCaptcha Validation
To implement Google reCaptcha
, you'll need a ReCaptcha site key and secret key, which you can get by registering your site with
Google's ReCaptcha service. That will provide you with two API keys, SITE KEY
, and SECRET KEY
, to validate the user.
It is a good practice to store these keys in environment variables for security reasons. In below code examples, I refer to them as process.env.REACT_APP_SITE_KEY
and process.env.REACT_APP_SECRET_KEY
.
Install dependencies
Install Google reCaptcha
by running the below command:
npm install --save react-google-recaptcha
or
yarn add react-google-recaptcha
Setup the ReCAPTCHA
Step 1: ReCAPTCHA component in React Js
Here is how to set up the reCaptcha component in a React Js component. Note that the ReCAPTCHA
component has two props. I use the ref to obtain the value from the ReCAPTCHA
component and reset the component after every submission.
import { useRef, useState } from 'react'
import ReCAPTCHA from 'react-google-recaptcha'
export default function SignupForm() {
const captchaReference = useRef(null)
const [name, setName] = useState('')
const [captchaStatus, setCaptchaStatus] = useState({ success: false, message: '' })
const submitForm = async (e) => {
e.preventDefault()
const captcha = captchaReference.current.getValue();
captchaReference.current.reset()
const response = await fetch(
`http://localhost:3002/submit-form`,
{
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify({ captcha, name })
}
);
const captchaValidation = await response.json();
setCaptchaStatus(captchaValidation)
}
return (
<form onSubmit={submitForm}>
<div>Name: <input type="text" value={name} onChange={(e) => setName(e.target.value)} /></div>
<ReCAPTCHA
sitekey={process.env.REACT_APP_SITE_KEY}
ref={captchaReference}
/>
<p>{captchaStatus.message}</p>
<input type='submit' value='Submit' />
</form>
)
}
Step 2: Validating reCaptcha token on the server
The second validation stage happens in the server. In the above component, I capture the user form details and the captcha token and submit them to the server to process further. Here is a simple Express server to represent the backend.
const express = require('express');
const axios = require('axios');
const app = express();
const cors = require('cors')
app.use(cors(), express.json())
app.post('/submit-form', async (req, res) => {
const { captcha, name } = req.body;
try {
const googleResponse = await axios.post(`https://www.google.com/recaptcha/api/siteverify?secret=${process.env.SECRET_KEY}&response=${captcha}`);
if (googleResponse.data.success) {
saveData(name)
res.json({ success: true, message: 'Form submitted' });
} else {
res.json({ success: false, message: 'Captcha validation failed' });
}
} catch (err) {
res.json({ success: false, message: 'Error occurred while validating captcha' });
}
});
app.listen(3002, () => console.log('Server started'));
I validate the user's captcha token on the server with the secret key. This validation should happen on the server side due to CORS restrictions. Google API will reject any requests coming from the browser.