How To Add BotDetect CAPTCHA Protection to React Application

Unlike Recaptcha the Stalker -- BotDetect CAPTCHA works in China! Licensable source-code; self-hosted -- doesn't stalk -- nor does it slurp your form-data! Think: GDPR & LGPD!

CAPTCHA Integration Steps

  1. Integration in React application
  2. Captcha Generator server-side configuration

I. Integration in React app

BotDetect Captcha protection can be added to your React applications using the BotDetect CAPTCHA React Component. Displaying the Captcha challenge can be as simple as:

<Captcha styleName="exampleCaptcha" ref={(captcha) => {this.captcha = captcha}} />

and using validateUnsafe(callback) method to validate Captcha code on form submit:

...
import { Captcha } from 'reactjs-captcha';

class Example extends React.Component {

  constructor(props) {
    super(props);
  }
  
  // On form submit.
  formSubmit(event) {
    
    this.captcha.validateUnsafe(function(isCaptchaCodeCorrect) {

      if (isCaptchaCodeCorrect) {
        // Captcha code is correct
      } else {
        // Captcha code is incorrect
      }

    });

    event.preventDefault();
  }

  render() {
    ...
  }
}

export default Example;

You can see how BotDetect Captcha protection is added to a simple React form by running the BotDetect Captcha integration code examples coming with the each BotDetect product's free download package.

Follows the step by step guide on how to integrate BotDetect into your React application. Backend related code snippets come in 3 different techs (.NET, Java & PHP) in order to cover whatever is the technology of your choice.

Install BotDetect CAPTCHA React Component

Step 1: Install BotDetect Captcha React Component

Step 2: Import React Captcha Component into Your Component

import { Captcha, captchaSettings } from 'reactjs-captcha';

Step 3: Set Captcha Endpoint

The following step ensures that BotDetect CAPTCHA library works properly in your React application. Please follow it carefully.

class Example extends React.Component {

    constructor(props) {
        super(props);

        captchaSettings.set({
            captchaEndpoint: 'captcha-endpoint/BotDetectCaptcha.ashx'
        });
    }

    ...
}

To render Captcha in your React application, the React Captcha Component requires configuring the BotDetect ASP.NET Captcha endpoint. Use the captchaSettings module's to set captchaEndpoint option value in your component's constructor.

Notes:

  • captcha-endpoint: is an example path, you need to set exact path to where you have deployed BotDetect ASP.NET Captcha library. If you deployed BotDetect ASP.NET Captcha library in the root of your domain, then you don't need to set this path.
  • /BotDetectCaptcha.ashx: is SimpleCaptchaHandler path, which is described on Register BotDetect HttpHandler for CAPTCHA Requests guide below.

To ensure that you have set a right path to captchaEndpoint setting, check it by opening the following url in your browser: http://yourdomain.com/captcha-endpoint/BotDetectCaptcha.ashx (replace the exact path of your domain). If this results with an error message ("unknown command") then you set the right path, since that is the BotDetect Captcha who responded error (when you fail to set correct path, then your server will respond with 404 instead). Please note, in order to perform this check, BotDetect Captcha Generator needs to be installed & deployed to your server.

Display BotDetect CAPTCHA In Your React View

Displaying the Captcha challenge can be as simple as:

class Example extends React.Component {

    ...

    render() {
        return (
            <Captcha styleName="exampleCaptcha" ref={(captcha) => {this.captcha = captcha}} />
        )
    }

}

Rendering Captcha component in your React component will add Captcha markup to your form. With styleName attribute, captcha style is assigned to rendered Captcha. Captcha style is defined in botdetect.xml configuration file and it defines various captcha options settings.

Besides that, BotDetect client-side object needs to be present in your component, that exposes all Captcha workflow functions and vars. Thus, use ref as shown right above in order to access Captcha element and we will use it to get the BotDetect client-side object later during the form submission part of the workflow.

Captcha Validation

Client-side Captcha validation in your React application

BotDetect Captcha React Component provides two approaches to validate Captcha on client-side.

  • Using validateUnsafe(callback) method to validate Captcha code on form submit:
...
import { Captcha } from 'reactjs-captcha';

class Example extends React.Component {

  constructor(props) {
    super(props);
  }
  
  // On form submit.
  formSubmit(event) {
    
    this.captcha.validateUnsafe(function(isCaptchaCodeCorrect) {

      if (isCaptchaCodeCorrect) {
        // Captcha code is correct
      } else {
        // Captcha code is incorrect
      }

    });

    event.preventDefault();
  }

  render() {
    ...
  }
}

export default Example;

OR:

  • Using data-correct-captcha directive attribute to validate Captcha code on blur event:

Adding the data-correct-captcha attribute in the captcha code input element assures that BotDetect React Component will automatically validate captcha code on blur event.

<input
  type="text"
  name="captchaCode"
  id="captchaCode"
  data-correct-captcha
/>

And you can check the captcha validation result by listening to the custom validatecaptcha event as the code shown below.

document.getElementById('captchaCode').addEventListener('validatecaptcha', function (e) {
    const isCorrect = e.detail;
    if (isCorrect) {
      // UI Captcha validation passed
    } else {
      // UI Captcha validation failed
    }
  })

These client-side captcha validations are just an usability improvement that you may use or not -- they do not protect your form from spammers at all.

As you are protecting some server-side action you must validate a Captcha at the server-side before executing that protected action.

Server-side Captcha validation

formSubmit(event) {
  const captcha = this.captcha.getInstance();

  // captcha id for validating captcha at server-side
  const captchaId = captcha.captchaId;

  // captcha code input value for validating captcha at server-side
  const captchaCode = document.getElementById('captchaCode').value;

  const postData = {
    captchaId: captchaId,
    captchaCode: captchaCode
  };
  
  axios.post('/your-server-api-url', postData)
    .then(response => {
      if (response.data.success) {
        // captcha validation passed at server-side
      } else {
        // captcha validation failed at server-side
      }

      // we should reload captcha image after server-side validation is completed
      // in order to update new captcha code for current captcha id
      captcha.reloadImage();
    }).catch(function (error) {
      throw new Error(error);
    });

  event.preventDefault();
}

To validate Captcha at server-side, we need to send captchaId property of captcha client-side object and captcha code visitor submited to server-side.

Once request finished, we always reload Captcha by calling the reloadImage() function of captcha client-side object. This is needed to generate the new captcha code for the current captcha id.

At server-side API, we take captchaId and captchaCode values sent from client-side, and using Validate(captchaCode, captchaId) method of SimpleCaptcha instance we validate Captcha code. Finally, we write the validation result as json string for sending it back to client.


  • Server-side Captcha validation in Web API 2:
using BotDetect.Web;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;

namespace ProductApp.Controllers
{
    public class ExampleController : ApiController
    {
        // POST api/example
        public HttpResponseMessage Post([FromBody]Models.BasicForm value)
        {
            // validate captcha
            SimpleCaptcha captcha = new SimpleCaptcha();
            bool isHuman = captcha.Validate(value.CaptchaCode, value.CaptchaId);

            if (isHuman)
            {
                // Captcha validation passed
                // TODO: do whatever you want here
            }

            // the object that stores validation result
            Dictionary<string, bool> validationResult = new Dictionary<string, bool>();
            validationResult.Add("success", isHuman);

            // write the validation result as json string for sending it back to client
            string jsonString = JsonConvert.SerializeObject(validationResult);
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
            response.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");

            return response;
        }
    }
}

  • Server-side Captcha validation in a Generic Handler:
<%@ WebHandler Language="C#" Class="BasicHandler" %>
using System;
using System.Web;
using System.IO;
using Newtonsoft.Json;
using System.Collections.Generic;
using BotDetect.Web;

public class BasicHandler : IHttpHandler
{
    public void ProcessRequest (HttpContext context)
    {
        if (HttpContext.Current.Request.HttpMethod == "POST")
        {
            string dataJson = new StreamReader(context.Request.InputStream).ReadToEnd();

            Dictionary<string, string> formDataObj = new Dictionary<string, string>();
            formDataObj = JsonConvert.DeserializeObject<Dictionary<string, string>>(dataJson);

            string captchaId = formDataObj["captchaId"];
            string captchaCode = formDataObj["captchaCode"];

            // validate captcha
            SimpleCaptcha captcha = new SimpleCaptcha();
            bool isHuman = captcha.Validate(captchaCode, captchaId);

            if (isHuman)
            {
                // Captcha validation passed
                // TODO: do whatever you want here
            }

            // the object that stores validation result
            Dictionary<string, bool> validationResult = new Dictionary<string, bool>();
            validationResult.Add("success", isHuman);

            // write the validation result as json string for sending it back to client
            context.Response.ContentType = "application/json; charset=utf-8";
            context.Response.Write(JsonConvert.SerializeObject(validationResult));
        }
    }
}

II. Captcha Generator server-side configuration

Install BotDetect ASP.NET Captcha library on Server-side

Before integrating BotDetect Captcha in your React application, you need to ensure you have installed BotDetect ASP.NET Captcha library on your server where your React application back end is hosted. Here is where you can find how:

Configure BotDetect Captcha options

<?xml version="1.0" encoding="UTF-8"?>
<botdetect xmlns="https://captcha.com/schema/net" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/net 
      https://captcha.com/schema/net/botdetect-4.4.0.xsd">

  <captchaStyles>
    
    <captchaStyle>
      <name>exampleCaptcha</name>
      <userInputID>captchaCode</userInputID>
      <codeLength>6</codeLength>
    </captchaStyle>

    <captchaStyle>
      <name>loginCaptcha</name>
      <userInputID>captchaCode</userInputID>
      <codeLength>4-6</codeLength>
      <codeStyle>Alphanumeric</codeStyle>
    </captchaStyle>

  </captchaStyles>

</botdetect>

To configure captcha options, you need to create botdetect.xml configuration file (with xml content like the one above this) in root folder of your project. The full list of available Captcha configuration options and related instructions at the Captcha configuration options page.

Please Note

React Captcha Component requires the new experimental Simple API that is currently available in BotDetect Java v4.0.Beta3+, BotDetect PHP v4.2.0+, as well as in BotDetect ASP.NET v4.4.0 build for legacy .NET.
The Simple API for ASP.NET Core will be available in the BotDetect ASP.NET v4.4.1 that will be released in few weeks time.