Angular Basic CAPTCHA Code Example

  1. Client-side
    1. Angular 2/4/5/6/7+
    2. AngularJS 1.x
  2. Server-side

I. Client-side

a) Angular 2/4/5/6/7+

The Angular Basic Captcha code example shows the most basic source code required to protect an Angular application with BotDetect CAPTCHA and validate the user input.

It can be used as a starting point when you first learn how to use BotDetect in your Angular application.

Download the BotDetect ASP.NET CAPTCHA Library and run this example

Installed Location

By default, the Angular Basic CAPTCHA code example project is installed at:
C:\Program Files\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\WebApp\SimpleAPI\AngularCaptchaExample

You can also run it from the BotDetect Start Menu:
Programs > Captcha Inc > BotDetect 4 CAPTCHA Component > ASP.NET > ASP.NET Examples > Run .NET Examples

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppRoutingModule } from './app-routing.module';
import { BotDetectCaptchaModule } from 'angular-captcha';

import { AppComponent } from './app.component';
import { BasicComponent }   from './basic/basic.component';

import { ValuesPipe } from './values.pipe';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule,
    BotDetectCaptchaModule.forRoot({
      captchaEndpoint: 'BotDetectCaptcha.ashx',
    })
  ],
  declarations: [
    AppComponent,
    BasicComponent,
    ValuesPipe
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

We import BotDetectCaptchaModule, then declare it in metadata imports of NgModule and configure BotDetect Java Captcha path in captchaEndpoint settings.

basic.component.html

<form novalidate #f="ngForm" (ngSubmit)="validate(f.value, f.valid)">

  <div class="alert alert-success" *ngIf="successMessages">
    {{ successMessages }}
  </div>

  <div class="alert alert-error" *ngIf="errorMessages">
    {{ errorMessages }}
  </div>

  <!-- show captcha html -->
  <botdetect-captcha styleName="angularBasicCaptcha"></botdetect-captcha>  

  <label>
    <span>Retype the characters from the picture:</span>
    <input
      type="text"
      id="captchaCode"
      name="captchaCode"
      ngModel
      #captchaCode="ngModel"
    >
  </label>

  <button type="submit">Validate</button>
</form>

Adding Captcha protection to the Angular form is as simple as using botdetect-captcha element, which is provided by BotDetect Captcha Angular Module and set to styleName attribute a Captcha style name defined in botdetect.xml configuration file below.

basic.component.ts

import { Component, ViewChild } from '@angular/core';
import { Observable } from 'rxjs/Rx';

import { CaptchaComponent } from 'angular-captcha';

import { BasicService } from './basic.service';

@Component({
  moduleId: module.id,
  selector: 'basic-form',
  templateUrl: 'basic.component.html',
  styleUrls: ['basic.component.css'],
  providers: [BasicService]
})
export class BasicComponent {

  /**
   * Captcha validation messages.
   */
  errorMessages: string;
  successMessages: string;

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

  constructor(private basicService: BasicService) { }

  /**
   * Validate captcha at server-side.
   */
  validate(value, valid): void {
    // use validateUnsafe() method to perform client-side captcha validation
    this.captchaComponent.validateUnsafe((isCaptchaCodeCorrect: boolean) => {

      if (isCaptchaCodeCorrect) {

        // after UI form validation passed, 
        // we will need to validate captcha at server-side once before we save form data in database, etc.

        const postData = {
          captchaCode: this.captchaComponent.captchaCode,
          captchaId: this.captchaComponent.captchaId
        };
      
        this.basicService.send(postData)
          .subscribe(
            response => {
              if (response.success) {
                // captcha, other form data passed and the data is also stored in database
                this.successMessages = 'Your message was sent successfully!';
                this.errorMessages = '';
              } else {
                // captcha validation failed at server-side
                this.errorMessages = 'CAPTCHA validation falied.';
                this.successMessages = '';
              }

              // always reload captcha image after validating captcha at server-side 
              // in order to update new captcha code for current captcha id
              this.captchaComponent.reloadImage();
            },
            error => {
              throw new Error(error);
            });
      } else {
        this.errorMessages = 'CAPTCHA validation falied.';
        this.successMessages = '';
      }
    });
  }

}

In this component, we inject CaptchaComponent into BasicComponent using @ViewChild.

On form submit, we use validateUnsafe() method to perform client-side captcha validation and we also need to send both captcha id (via captchaComponent.captchaId property) and captcha code visitor submited (via captchaComponent.captchaCode property) to server-side to validate Captcha code once.

Once request finished, 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.

basic.service.ts

import { Injectable }    from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';

import { Observable } from 'rxjs/Rx';

@Injectable()
export class BasicService {

  // basic api url
  basicUrl = 'BasicHandler.ashx';

  constructor(private http: Http) { }

  validateCaptcha(data: Object): Observable<any> {
    const headers = new Headers({ 'Content-Type': 'application/json' });
    const options = new RequestOptions({ headers: headers });

    return this.http.post(this.basicUrl, data, options)
      .map((response: Response) => response.json())
      .catch((error:any) => Observable.throw(error.json().error));
  }
}

In this BasicService, we simply add a function that posts data to the basic api url using Http post of HttpModule.

b) AngularJS 1.x

The AngularJS Basic Captcha code example shows the most basic source code required to protect an AngularJS application with BotDetect CAPTCHA and validate the user input.

It can be used as a starting point when you first learn how to use BotDetect in your AngularJS application.

Download the BotDetect ASP.NET CAPTCHA Library and run this example

Installed Location

By default, the AngularJS Basic CAPTCHA code example project is installed at:
C:\Program Files\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\WebApp\SimpleAPI\AngularJSCaptchaExample

You can also run it from the BotDetect Start Menu:
Programs > Captcha Inc > BotDetect 4 CAPTCHA Component > ASP.NET > ASP.NET Examples > Run .NET Examples

basic-captcha.html

<form name="basicForm" novalidate ng-controller="BasicController" ng-submit="validate(basicForm.$valid)">

  <div class="alert alert-success" ng-show="successMessages">
    {{ successMessages }}
  </div>

  <div class="alert alert-error" ng-show="errorMessages">
    {{ errorMessages }}
  </div>

  <!-- show Captcha image html-->
  <botdetect-captcha styleName="angularBasicCaptcha"></botdetect-captcha>

  <label>
    <span>Retype the characters from the picture:</span>
    <!-- captcha code user input textbox -->
    <input type="text" name="captchaCode" ng-model="captchaCode" id="captchaCode" autocomplete="off">
  </label>


  <button type="submit">Validate</button>
</form>

Adding Captcha protection to the AngularJS form is as simple as using botdetect-captcha element, which is provided by BotDetect Captcha AngularJS Module and set to styleName attribute a Captcha style name defined in botdetect.xml configuration file below.

app.js

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

app.config(function($routeProvider, captchaSettingsProvider) {
  captchaSettingsProvider.setSettings({
    captchaEndpoint: '/bdc4-simple-api-angularjs-captcha-example/botdetectcaptcha'
  });
});

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

  // captcha validation messages
  $scope.successMessages = '';
  $scope.errorMessages = '';
  
  // basic captcha url
  var basicUrl = 'BasicHandler.ashx';
  
  $scope.validate = function() {

    // create new BotDetect AngularJS Captcha instance
    var captcha = new Captcha();

    // use validateUnsafe() method to perform client-side captcha validation
    captcha.validateUnsafe(function(isCaptchaCodeCorrect) {

      if (isCaptchaCodeCorrect) {
        
        // after UI form validation passed, 
        // we will need to validate captcha at server-side once before we save form data in database, etc.
        
        // 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: basicUrl,
          data: JSON.stringify(postData)
        })
          .then(function(response) {
            if (response.data.success) {
              // captcha validation passed at server-side
              $scope.successMessages = 'CAPTCHA validation passed.';
              $scope.errorMessages = null;
            } else {
              // captcha validation failed at server-side
              $scope.errorMessages = 'CAPTCHA validation falied.';
              $scope.successMessages = null;
            }
            
            // always reload captcha image after validating captcha at server-side 
            // in order to update new captcha code for current captcha id
            captcha.reloadImage();
          }, function(error) {
            console.log(error.data);
          });
      } else {
        $scope.errorMessages = 'CAPTCHA validation falied.';
        $scope.successMessages = null;
      }
    });
  };
   
});

First, we add BotDetectCaptcha to the app module as a dependency and configure BotDetect Java Captcha path to captchaEndpoint settings in config function.

In the code above, we inject Captcha into BasicController.

On form submit, we use validateUnsafe() method to perform client-side captcha validation and we aslo need to send captchaId property of Captcha object and captcha code visitors submitted to server-side to validate Captcha code once at server-side api.

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

II. Server-side

botdetect.xml

<?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>angularBasicCaptcha</name>
      <userInputID>captchaCode</userInputID>
      <codeLength>3-5</codeLength>
    </captchaStyle>
  </captchaStyles>

</botdetect>

In botdetect.xml, we configure some captcha options for our angular basic captcha. You can find a full list of available SimpleCaptcha configuration options and related instructions at the SimpleCaptcha configuration options page.

BasicHandler.ashx

<%@ 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));
        }
        else
        {
            context.Response.ContentType = "text/plain";
            context.Response.Write("HTTP GET request is not allowed.");
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

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

Please Note

Angular Captcha Module 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.