DEV Community

Saksham Negi
Saksham Negi

Posted on

2 1 1 1 1

Implement google reCaptcha v3 in your React and Go application

CAPTCHA stands for Completely Automated Public Turing Test to tell Computers and Humans apart. It is a type of security measure which protects your application against bots and helps you detect abusive traffic. Google reCaptcha v3 is a service provided by google which uses risk analysis techniques to detect and block spam traffic without user interaction. Let’s us see how to implement it in React and Go.

How it works

The google reCaptcha v3 service gives two keys- a site key and a secret key for validation. The site key is used for token generation in the client side and secret key is used for validation in server side. The token generated using site key is sent to the server for verification. Generally, it is sent during any form submission along with the form values. In the server, the the request is verified using the endpoint:

https://www.google.com/recaptcha/api/siteverify
Enter fullscreen mode Exit fullscreen mode

The secret key stored in server and the token received from client are sent in the body of this request as x-www-form-urlencoded values. It returns an error if the keys or token does not match. In case of successful request, it returns a score between 0.0 and 1.0 where 1.0 indicates a human and 0.0 indicates a bot. The threshold value to block or allow the traffic is set according to the needs of our application. More on this later in the article.

Service Setup

  1. Go to https://www.google.com/recaptcha/admin/create and register your application.
  2. Enter your app name in label.
  3. Select reCaptcha type as Score based (v3).
  4. Enter your domain name in which your app will be hosted. For local testing, add localhost in it.
  5. Once you finish, you’ll get the site key and secret key. Copy them both as we will use them later.

Code Setup

  • Install react-google-recaptcha-v3 package:
npm i react-google-recaptcha-v3
Enter fullscreen mode Exit fullscreen mode
  • Get reCaptcha token and send it to the server:
import React, { useState } from "react";
import { GoogleReCaptchaProvider, useGoogleReCaptcha } from "react-google-recaptcha-v3";

const RECAPTCHA_SITE_KEY = "your-site-key"; // Replace with your actual site key

const MyForm = () => {
  const { executeRecaptcha } = useGoogleReCaptcha();
  const [formData, setFormData] = useState({});

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!executeRecaptcha) {
      console.log("reCAPTCHA not loaded yet");
      return;
    }

    // Execute reCAPTCHA to get the token
    const recaptchaToken = await executeRecaptcha("submit");

    // Send form data + token to backend
    const response = await fetch("http://localhost:8080/api/verify-recaptcha", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ ...formData, recaptchaToken }),
    });

    const data = await response.json();
    if (data.success) {
      alert("Form submitted successfully!");
    } else {
      alert("reCAPTCHA verification failed. Please try again.");
    }
  };

  return (
  // your form
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
};

// Wrap your app with GoogleReCaptchaProvider
const App = () => (
  <GoogleReCaptchaProvider reCaptchaKey={RECAPTCHA_SITE_KEY}>
    <MyForm />
  </GoogleReCaptchaProvider>
);

export default App;
Enter fullscreen mode Exit fullscreen mode
  • Verify the token and process the form submission:
type RecaptchaResponse struct {
    Success bool    `json:"success"`
    Score   float64 `json:"score"`
}

func VerifyRecaptchaToken(token string) error {
    var recaptchaResponse RecaptchaResponse

    secretKey := os.Getenv("RECAPTCHA_SECRET_TOKEN")
    resp, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify",
        url.Values{
            "secret":   {secretKey},
            "response": {token},
        })
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if err := json.NewDecoder(resp.Body).Decode(&recaptchaResponse); err != nil {
        return err
    }

    thresholdNumber := constant.DEFAULT_RECAPTCHA_THRESHOLD
    // verification failed or score less than set threshold
    if !recaptchaResponse.Success || recaptchaResponse.Score <= thresholdNumber {
        return errors.New("verification failed")
    }

    // process the form submission
    return nil
}
Enter fullscreen mode Exit fullscreen mode

Score and Threshold

As we know now, the reCaptcha verification API returns a score. The request is blocked or allowed based on that score and the set threshold. The threshold value is set according to the application. Generally a value of 0.5 as threshold is widely used. It means score less than 0.5 will be marked as a bot and anything greater than that is allowed.

If the user on the application has logged in, the chances of bot requests become less. In these cases we can set the threshold around ~0.5. If the application has an open form, without authentication, increasing the threshold should be considered — preferably somewhere around ~0.7 as the chances of bot requests are higher.

The behaviour of the requests with low scores can also be configured. Some common methods of dealing with such requests are OTP/email verification, reCaptcha v2(challenge), manual reviews or blocking them straight away.

Conclusion

I hope you enjoyed the article, any suggestions/improvements are welcome.

Reach out to me at sakshamnegi.dev@gmail.com for any questions, feedback, or collaboration opportunities.

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong · web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video 🌶️🔥

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Build With Me: AI-Powered Adaptive Web Scraper with LLMs

Join us for a hands-on session with Zia Ahmad where we build an AI-driven web scraper that adapts to site changes in real-time. Code along and level up your automation skills.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️