How To Add BotDetect CAPTCHA Protection to React Application

BotDetect CAPTCHA works in China -- and it does not stalk you around! Read more...

CAPTCHA Integration Steps

  1. Implementation
  2. Configuration

I. Implementation

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 checking user input on blur event at client-side by listening the custom validatecaptcha event:

<input
  type="text"
  name="captchaCode"
  id="captchaCode"
  data-correct-captcha
>
document.getElementById('captchaCode').addEventListener('validatecaptcha', function (e) {
    const isCorrect = e.detail;
    if (isCorrect) {
      // UI Captcha validation passed
    } else {
      // UI Captcha validation failed
    }
  })

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

class Example extends React.Component {

    constructor(props) {
        super(props);

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

    ...
}

To render Captcha in your React application, the React Captcha Component requires configuring the BotDetect Java 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 the exact path to where you have installed BotDetect Java Captcha library before. In case you installed BotDetect Java Captcha library at root of your domain, you don't need to set this path.
  • /botdetectcaptcha: is SimpleCaptchaServlet path, which is described on Register SimpleCaptchaServlet guide below.

Check if you set captchaEndpoint option to a valid path by opening the following url in your browser: http://yourdomain.com/captcha-endpoint/botdetectcaptcha. If you receive ("unknown command") response from BotDetect Captcha, then your captcha endpoint is set to the right path.

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 values. 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 when form is submitted.

Captcha Validation in React application

Client-side Captcha validation

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
    }
  })

Please note that, this client-side captcha validation is just an UI validation, it does not protect your form from spammers yet. You are protecting some server-side action, and therefore you need to validate Captcha at a server-side.

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 a Servlet looks in this way:
....

import com.captcha.botdetect.web.servlet.SimpleCaptcha;

public class ExampleServlet extends HttpServlet {

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    PrintWriter out = response.getWriter();
    Gson gson = new Gson();

    response.setContentType("application/json; charset=utf-8");

    JsonParser parser = new JsonParser();
    JsonObject formDataObj = (JsonObject) parser.parse(request.getReader());

    String captchaId = formDataObj.get("captchaId").getAsString();
    String captchaCode = formDataObj.get("captchaCode").getAsString();

    // validate captcha
    SimpleCaptcha captcha = SimpleCaptcha.load(request);
    boolean isHuman = captcha.validate(captchaCode, captchaId);

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

    // the object that stores validation result
    ExampleValidationResult validationResult = new ExampleValidationResult();
    validationResult.setSuccess(isHuman);

    try {
      // write the validation result as json string for sending it back to client
      out.write(gson.toJson(validationResult));
    } catch(Exception ex) {
      out.write(ex.getMessage());
    } finally {
      out.close();
    }
  }
}

  • Server-side Captcha validation in a Spring MVC Controller looks in this way:
...
import com.captcha.botdetect.web.servlet.SimpleCaptcha;

@Controller
public class ExampleController {

  @RequestMapping(value = "basic-captcha", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
  @ResponseBody
  public String exampleCaptcha(HttpServletRequest request) {
    JsonParser parser = new JsonParser();
    JsonObject formDataObj = null;
    boolean result = false;

    try {
      formDataObj = (JsonObject) parser.parse(request.getReader());
    } catch (IOException ex) { }

    if (formDataObj != null) {
      String captchaId = formDataObj.get("captchaId").getAsString();
      String captchaCode = formDataObj.get("captchaCode").getAsString();

      // validate captcha
      SimpleCaptcha captcha = SimpleCaptcha.load(request);
      boolean isHuman = captcha.validate(captchaCode, captchaId);

      result = isHuman;
    }

    return "{\"success\":" + result.toString() + "}";
  }
}

  • Server-side Captcha validation in a Struts Action looks in this way:
...
import com.captcha.botdetect.web.servlet.SimpleCaptcha;

public class ExampleAction {

  private boolean success = false;

  public boolean isSuccess() {
    return success;
  }

  public String execute() {
    HttpServletRequest request = ServletActionContext.getRequest();

    if (!request.getMethod().equalsIgnoreCase("post")) {
      return Action.ERROR;
    }

    Map<String, String> mapParams = request.getParameterMap();
    Set<String> setKeys = mapParams.keySet();
    Iterator<String> temp = setKeys.iterator();
    String data = temp.next();

    JsonParser parser = new JsonParser();
    JsonObject formDataObj = (JsonObject) parser.parse(data);

    if (formDataObj != null) {
      String captchaId = formDataObj.get("captchaId").getAsString();
      String captchaCode = formDataObj.get("captchaCode").getAsString();

      // validate captcha
      SimpleCaptcha captcha = SimpleCaptcha.load(request);
      boolean isHuman = captcha.validate(captchaCode, captchaId);

      this.success = isHuman;
    }

    return Action.SUCCESS;
  }
}

II. Configuration

Install BotDetect Java Captcha library on Server-side

Before integrating BotDetect Captcha in your React application, you need to ensure you have installed BotDetect Java Captcha library on your server where your React application backend 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/java"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/java 
      https://captcha.com/schema/java/botdetect-BD4_Java_LC.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 WEB-INF/ folder. 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 version (4.0.Beta3+) and BotDetect PHP version (4.2.0+). Click here to find out when the Simple API will be available in BotDetect ASP.NET.