How To Add BotDetect CAPTCHA Protection to Angular Application

Please Note

Angular Captcha Module requires the new experimental Simple API that is currently available only in BotDetect Java version (4.0.Beta3+). Click here to find out when the Simple API will be available in BotDetect ASP.NET, PHP, and Classic ASP.

CAPTCHA Integration Steps

  1. Client-side
    1. AngularJS 1.x
    2. Angular 2+
  2. Server-side

I. Client-side

a) AngularJS 1.x

BotDetect Captcha protection can be added to your AngularJS applications using the BotDetect CAPTCHA AngularJS Module, a custom botdetect-captcha directive element to display Captcha Html markup and a custom correct-captcha directive attribute to validate Captcha code on blur event at client-side.

Displaying the Captcha challenge can be as simple as:

<botdetect-captcha styleName="exampleCaptcha"></botdetect-captcha>

And checking user input on blur event at client-side:

<input 
  type="text" 
  id="captchaCode"
  name="captchaCode"
  ng-model="captchaCode" 
  correct-captcha
>

To see example of BotDetect Captcha protection in a simple AngularJS form run the BotDetect Captcha integration code examples coming with the BotDetect download package.

(Please Note: Currently, AngularJS module is only supported by BotDetect Java, but support in PHP and ASP.NET versions is coming soon.)

Install BotDetect CAPTCHA AngularJS Module

Step 1: Install BotDetect Captcha AngularJS Module

Step 2: Include BotDetect Captcha AngularJS Module in your web app

<script src="node_modules/angularjs-captcha/dist/angularjs-captcha.min.js"></script>

Step 3: Add BotDetect Captcha AngularJS Module to your AngularJS module

This step is very important to make sure that BotDetect CAPTCHA library works properly in your AngularJS application, so please follow it carefully.

var app = angular.module('app', ['BotDetectCaptcha']);

app.config(function(captchaSettingsProvider) {
  ...
  
  captchaSettingsProvider.setSettings({
    captchaEndpoint: '/botdetect-java-captcha-api-path-at-server-side/botdetectcaptcha'
  });
});

We add BotDetectCaptcha module to your AngularJS module as a dependency. It requires to configure BotDetect Java Captcha path to captchaEndpoint setting and in order to do this, in config function, we inject captchaSettingsProvider and then invoke setSettings() function as the code right above.

Before you set the path to captchaEndpoint setting, we need to clarify what we set here:

  • /botdetect-java-captcha-api-path-at-server-side: is an example path, you need to set exact path to where you have installed BotDetect Java Captcha library before. In case you install BotDetect Java Captcha library at root of your domain, then you won't need to set this path.
  • /botdetectcaptcha: is SimpleCaptchaServlet path, which is described on Register SimpleCaptchaServlet 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/botdetect-java-captcha-api-path-at-server-side/botdetectcaptcha (replace the exact path of your domain). If you see any error messages ("unknown command") thrown by BotDetect Captcha from this url, then you set the right path.

Display BotDetect CAPTCHA In Your AngularJS Template

Displaying the Captcha challenge can be as simple as:

<botdetect-captcha styleName="exampleCaptcha"></botdetect-captcha>

BotDetect Captcha AngularJS Module provides botdetect-captcha element to add Captcha in your forms. It has styleName attribute, which you can assign it a captcha style name defined in botdetect.xml configuration file.

Validate the Captcha in your AngularJS application

Client-side validate the Captcha

BotDetect Captcha AngularJS Module provides correct-captcha directive attribute to validate Captcha code on blur event:

<input 
  type="text" 
  id="captchaCode"
  name="captchaCode"
  ng-model="captchaCode" 
  correct-captcha
>

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 validate the Captcha

var app = angular.module('app', ['BotDetectCaptcha']);

...

app.controller('ExampleController', function($scope, $http, Captcha) {

  var exampleUrl = '/your-server-side-api-url';
  
  $scope.validate = function(valid) {

    if (!valid) {
      return;
    }

    // create new BotDetect Captcha instance
    var captcha = new Captcha();
    
    // captcha id for validating captcha at server-side
    var captchaId = captcha.captchaId;
    
    // captcha code input value for validating captcha at server-side
    var captchaCode = $scope.captchaCode;

    var postData = {
      captchaId: captchaId,
      captchaCode: captchaCode
    };
    
    $http({
      method: 'POST',
      url: exampleUrl,
      data: JSON.stringify(postData)
    })
      .then(function(response) {
        if (response.data.success) {
          // CAPTCHA validation passed at server-side
        } else {
          // CAPTCHA validation falied at client-side
        }
        
        // reload Captcha image
        captcha.reloadImage();
      }, function(error) {
        throw new Error(error.data);
      });
  };
   
});

In the code above, we inject Captcha service into ExampleController. The Captcha service exposes all Captcha workflow functions and values.

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

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

At server-side API (Java code), we take captchaId and captchaCode values sent from client-side, and using validate(captchaCode, captchaId) method of SimpleCaptcha instance we validate Captcha code:

....

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

Finally, we write the validation result as json string for sending it back to client.

Display Captcha error message in your AngularJS template

<div 
  class="error" 
  ng-show="exampleForm.captchaCode.$invalid && !exampleForm.captchaCode.$pristine"
  >
  Incorrect captcha code.
</div>

Assuming you have used the correct-code directive attribute in captcha code input field, to display captcha error message, simply check $invalid of captchaCode. If it returns true, this means that UI captcha validation failed.


b) Angular 2+

BotDetect Captcha protection can be added to your Angular applications using the BotDetect CAPTCHA Angular Module, a custom botdetect-captcha element to display Captcha Html markup and a custom correctCaptcha directive attribute to validate Captcha code on blur event at client-side.

Displaying the Captcha challenge can be as simple as:

<botdetect-captcha styleName="exampleCaptcha"></botdetect-captcha>

and checking user input on blur event at client-side:

<input
  type="text"
  id="captchaCode"
  name="captchaCode"
  #captchaCode="ngModel"
  ngModel
  correctCaptcha
>

To see example of BotDetect Captcha protection in a simple Angular form, run the BotDetect Captcha integration code examples coming with the BotDetect download package

(Please Note: Currently, Angular module is only supported by BotDetect Java, but support in PHP and ASP.NET versions is coming soon.)

Install BotDetect CAPTCHA Angular Module

Step 1: Install BotDetect Captcha Angular Module

Step 2: Load BotDetect Captcha Angular Module

If you use SystemJS, you will need to declare as bellow in your SystemJS config file:

System.config({
  paths: {
    // paths serve as alias
    'npm:': 'node_modules/'
  },
  map: {
    ...
    'angular-captcha': 'npm:angular-captcha'
  },
  packages: {
    ...
    'angular-captcha': {
      defaultExtension: 'js',
      main: 'index'
    },
  }
});

Step 3: Declare BotDetect Captcha Angular Module in your application

...
import { BotDetectCaptchaModule } from 'angular-captcha';

@NgModule({
  imports: [
    ...
    BotDetectCaptchaModule.forRoot({
      captchaEndpoint: '/botdetect-java-captcha-api-path-at-server-side/botdetectcaptcha'
    })
  ],
  ...
})
export class AppModule { }

In the code above, we import BotDetectCaptchaModule, and then declare it in metadata imports of the NgModule. In case you want to add Captcha in a child module, you will need to use forChild instead of forRoot in the code above.

The BotDetectCaptchaModule requires you to configure BotDetect Java Captcha path to captchaEndpoint setting.

Before you set the path to captchaEndpoint setting, we need to clarify what we should set here:

  • /botdetect-java-captcha-api-path-at-server-side: 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.

To ensure that you have set a right path by captchaEndpoint setting, check it by opening the following url in your browser: http://yourdomain.com/botdetect-java-captcha-api-path-at-server-side/botdetectcaptcha (replace the exact path of your domain). If you see any error messages ("unknown command") thrown by BotDetect Captcha from this url, then you set the right path.

Display BotDetect CAPTCHA In Your Angular Template

Displaying the Captcha challenge can be as simple as:

<botdetect-captcha styleName="exampleCaptcha"></botdetect-captcha>

BotDetect Captcha Angular Module provides botdetect-captcha element to add Captcha in your forms. With styleName attribute, you assign it a captcha style name defined in botdetect.xml configuration file.

Validate the Captcha in your Angular application

Client-side validate the Captcha

BotDetect Captcha Angular Module provides correctCaptcha directive attribute to validate Captcha code on blur event:

<input
  type="text"
  id="captchaCode"
  name="captchaCode"
  #captchaCode="ngModel"
  ngModel
  correctCaptcha
>

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 validate the Captcha

...

import { CaptchaComponent } from 'angular-captcha';

@Component({
  ...
})
export class ExampleComponent {

  /**
   * BotDetect CAPTCHA component.
   */
  @ViewChild(CaptchaComponent) captchaComponent: CaptchaComponent;

  constructor(private http: Http) { }

  /**
   * Validate captcha at server-side.
   */
  validate(value, valid): void {

    if (!valid) {
      return;
    }

    const exampleUrl = '/your-server-side-api-url';

    const postData = {
      captchaCode: value.captchaCode,
      captchaId: this.captchaComponent.captchaId
    }

    const headers = new Headers({ 'Content-Type': 'application/json' });
    const options = new RequestOptions({ headers: headers });

    this.http.post(exampleUrl, data, options)
      .map((response: Response) => {

        if (response.json().success) {
          // CAPTCHA validation passed at server-side
        } else {
          // CAPTCHA validation falied at client-side
        }

        // reload Captcha image
        this.captchaComponent.reloadImage();
      })
      .catch((error:any) => Observable.throw(error.json().error));
  }

}

In the code above, we inject CaptchaComponent into ExampleComponent using @ViewChild. The CaptchaComponent exposes all Captcha workflow functions and values.

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

On request finish, we always reload Captcha by calling the reloadImage() function of CaptchaComponent. This is needed to generate the new captcha code for the current captcha id.

At server-side API (Java code), we take captchaId and captchaCode values sent from client-side, and using validate(captchaCode, captchaId) method of SimpleCaptcha instance we validate Captcha code:

....

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

Finally, we write the validation result as json string for sending it back to client.

Display Captcha error message in your Angular template

<div
  class="error"
  *ngIf="captchaCode.errors?.incorrectCaptcha && !captchaCode.pristine"
  >
  Incorrect captcha code.
</div>

Assuming you have used the correctCaptcha directive attribute in captcha code input field, to display captcha error message, simply check if incorrectCaptcha property exists in captchaCode.errors object. If it exists, this means that UI captcha validation failed.


II. Server-side

Install BotDetect Java Captcha library on Server-side

Before integrating BotDetect Captcha in your Angular application, you need to ensure you have installed BotDetect Java Captcha library on your server where your Angular 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/java" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/java 
      https://captcha.com/schema/java/botdetect-4.0.beta3.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.