How to Add BotDetect PHP CAPTCHA Protection to CakePHP 2.6 Applications (BotDetect v3.0; deprecated)

Adding BotDetect PHP Captcha protection to your CakePHP MVC applications requires a slightly different approach than adding it to basic PHP websites, but is still straightforward. This page will guide you through the necessary steps and explain the available options.

First Time Here?

Check the BotDetect CakePHP 2.6 Captcha Quickstart for key integration steps.

Prerequisites

Table of Contents

The BotDetect CAPTCHA CakePHP Download Package

Because CakePHP is a MVC framework that leverages certain conventions to provide a rich set of functionality to PHP application developers, implementing BotDetect Captcha requires a layer of integration code to conform to those conventions. This enables BotDetect Captcha to integrate seamlessly into CakePHP applications and be used according to expectations of CakePHP developers.

Path Aliases Used Throughout This Guide

  • <MYCAKEAPP>: your CakePHP app directory (same as the APP_DIR PHP CakePHP constant)
  • <BDCAKEPACK>: the downloaded and extracted contents of the BotDetect Captcha CakePHP Package

For convenience purposes we are providing the BotDetect Captcha CakePHP integration code packaged as a CakePHP plugin.

You can get the whole BotDetect Captcha CakePHP integration package here. Included in this package is the integration code, a basic Captcha validation example, and a example showing use of BotDetect Captcha with CakePHP FormHelper and model validation.

(The BotDetect Captcha PHP Library is a required and separate download available here.)

The BotDetect CAPTCHA CakePHP Plugin

BotDetect CakePHP Plugin code, sans the Captcha library, is located at <BDCAKEPACK>/plugin/BotDetect.

The code includes a Captcha component for use in your application Controllers, and a separate Controller that handles Captcha image and sound requests. This Captcha Controller uses http://<MYCAKEAPP>/botdetect/captcha_handler and http://<MYCAKEAPP>/botdetect/captcha_resource/get Urls by default.

CakePHP Basic BotDetect CAPTCHA Example

This basic CakePHP 2.6 Captcha example shows how to use the BotDetect Captcha CakePHP plugin in your Controller and View code, and handling of basic Captcha user input validation.

  • Controller: <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples/ app/Controller/ExampleController.php
  • View: <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples/ app/View/Example/index.ctp

CakePHP Form Model Validation BotDetect CAPTCHA Example

This CakePHP 2.6 form model validation Captcha example shows how to use BotDetect Captcha with CakePHP form and validation functionality by implementing a simple contact form.

  • Controller: <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples /app/Controller/ContactController.php
  • Model: <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples /app/Model/Contact.php
  • View: <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples /app/View/Contact/index.ctp

CakePHP Auth BotDetect CAPTCHA Example

This CakePHP 2.6 Auth Captcha example shows how to use BotDetect Captcha with CakePHP Auth Component

  • Controller:
    • <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples /app/Controller/UsersController.php
  • View:
    • <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples /app/View/Users/login.ctp
    • <BDCAKEPACK>/bd-captcha-cakephp-2.6-examples
      /app/View/Users/add.ctp

The provided examples are available inside of a single CakePHP app via their respective controllers:

   http://<MYCAKEAPP>/example
   http://<MYCAKEAPP>/contact
   http://<MYCAKEAPP>/users/login
   http://<MYCAKEAPP>/users/add

You can copy the whole preconfigured CakePHP app from the BotDetect Captcha CakePHP Package somewhere on your development web server and examine it there.

1. Include BotDetect CAPTCHA in Your CakePHP MVC Application

Copy the Necessary BotDetect CAPTCHA Files

BotDetect CakePHP CAPTCHA Plugin folder structure screenshot

The base BotDetect Captcha library and CakePHP MVC Captcha integration code are distributed separately and need to be merged so you can use them in your CakePHP app.

1. BotDetect CakePHP CAPTCHA Plugin

Copy (the whole directory and all contents)
<BDCAKEPACK>/bd-captcha-cakephp-2.6-examples/ 
app/Plugin/BotDetect
to
<MYCAKEAPP>/Plugin/BotDetect

2. BotDetect CAPTCHA Library Code

Copy (the whole directory and all contents)
<BDCAKEPACK>/bd-captcha-cakephp-2.6-examples/ 
app/Lib
to
<MYCAKEAPP>/Lib

Load the BotDetect CAPTCHA Plugin in Your CakePHP Application

Your CakePHP app needs to be made aware of the BotDetect Captcha plugin. This is done inside your application's bootstrap (<MYCAKEAPP>/Config/bootstrap.php).

Add this code
CakePlugin::load(array(
    'BotDetect' => array('routes' => true)
));

at the end of your bootstrap.php file.

Please note that the whole MVC Captcha library is not loaded at every request; this is just letting the CakePHP application know about the plugin and leverages Cake's lazy-loading infrastructure to load the BotDetect code when it's actually needed.

That's it. BotDetect Captcha is ready to be used in your CakePHP application.

A Note On PHP Session Persistence

The BotDetect Captcha Library requires persistent per-user server storage to work properly. By default, it uses standard PHP Sessions, which is convenient in most use cases.

If your environment requires a different approach to handling Session data, you can implement your own Captcha persistence methods via the provided BotDetect Captcha persistence hooks in the lib/botdetect/CaptchaConfig.php file.

Also, the BotDetect Captcha CakePHP integration code has a single direct call to session_start() to make sure the Session is available for the component at the time of loading. This call is located in the startup method for the component, in <MYCAKEAPP>/Plugin/BotDetect/Controller/Component/CaptchaComponent.php, lines 58-60.

If your CakePHP application is handling Sessions in a non-standard way (i.e. there is no PHP $_SESSION global available), you may need to remove this call, as well as implementing the config file changes mentioned above.

2. Display BotDetect CAPTCHA In Your CakePHP View

Before displaying the Captcha in your View, the related Controller needs to load the BotDetect component and set a proper name for your Captcha instance. It also needs to pass the Captcha markup to the View, which can then display it alongside other form elements.

Load the BotDetect CAPTCHA CakePHP Component

The BotDetect CakePHP Captcha plugin uses the usual method of loading and configuring components inside of CakePHP.

class ExampleController extends AppController {
  // Your controller

  var $components = array(
    'BotDetect.Captcha' => array(
      'CaptchaId' => 'ExampleCaptcha', // a unique Id for the Captcha instance
      'UserInputId' => 'CaptchaCode' // Id of the Captcha code input textbox
    )
  );

The BotDetect MVC Captcha component is available in CakePHP code under the BotDetect plugin namespace. It's loaded to the $components array in your Controller, and is supplied a unique name through the CaptchaId component setting. Each individual Controller action including Captcha validation should use a unique CaptchaId value to avoid persistence name clashes.

The additional UserInputId setting is used to setup client-side functionality operating on the Captcha code input field.

Pass the BotDetect CAPTCHA HTML Markup to the CakePHP View

The CakePHP MVC Captcha component generates its own markup, which should be made available to your View. The Captcha Html is retrieved by calling the Html() method on the Captcha component object. It is then made available to the view by setting a variable with Controller::set().

class ExampleController extends AppController {
  // Your controller
  
  var $components = array(
    'BotDetect.Captcha' => array(
      'CaptchaId' => 'ExampleCaptcha', // a unique Id for the Captcha instance
      'UserInputId' => 'CaptchaCode' // Id of the Captcha code input textbox
    )
  );

  public function index(){
    // your controller action
    $this->set('captchaHtml', $this->Captcha->Html());
  }
}

The Captcha markup is now available inside your View's $captchaHtml variable.

Compose Your CakePHP View With BotDetect CAPTCHA Display

Inside your View's .ctp script, you should include some form elements alongside the Captcha display. You can use either straight markup or the CakePHP FormHelper. In a regular form with a submit button, you need an input field where the user retypes the characters shown in the Captcha image.

You display the image by outputting the $captchaHtml variable from the previous step:

echo $this->Form->create(false, array('action' => 'index'));
echo $captchaHtml;
echo $this->Form->input('CaptchaCode');
echo $this->Form->submit();
echo $this->Form->end();

You also need to add the BotDetect Captcha layout stylesheet, which CakePHP will include in the <head> of your page containing the Captcha:

echo $this->Html->css(CaptchaUrls::LayoutStylesheetUrl(), array('inline' => false));

The Captcha should now be visible and functioning in your View.

3. Validate the CAPTCHA In Your CakePHP Controller

After your Captcha is displayed alongside a form input field, you will want to validate the user submitted Captcha code in the Controller action. This should always be done before any sensitive processing, to confirm the submitted data is actually entered by a person and not a bot.

Validate the Submitted CAPTCHA Code User Input

The validation of Captcha code input should be done in the Controler->Action that is on the receiving end of the form submission (where the form action points to).

Usually, the submitted form data is available inside the CakePHP request object, by the same name you gave the Captcha code input field on the form where it was displayed. For example: $this->request->data['CaptchaCode'].

It is then a matter of calling the Validate() method of the Captcha component object and passing it the user input.

// assuming "CaptchaCode" input field id
$isHuman = $this->Captcha->Validate($this->request->data['CaptchaCode']);

unset($this->request->data['CaptchaCode']);

After Captcha validation, it is best to clear the previous user input automatically; since each Captcha code can only be validated once regardless of the validation result, keeping previous user input makes no sense.

Handle CAPTCHA Validation Failure / Success

You should then write some code to handle both Captcha validation success and failure. If it failed, you should abort further processing and display an error message; if it succeeded, you can proceed with the protected form action:

if ($isHuman) {
  // TODO: Captcha validation passed:
  // continue with form processing, knowing the submission was made by a human
} else {
  // TODO: Captcha validation failed:
  // abort sensitive action, return an error message
}

This will ensure that the sensitive action can not be automated and is only performed when a human fills out the form.


Please Note

The information on this page is out of date and applies to a deprecated version of BotDetect™ CAPTCHA (v3.0).

An up-to-date equivalent page for the latest BotDetect Captcha release (v4) is BotDetect v4 Captcha documentation index.

General information about the major improvements in the current BotDetect release can be found at the What's New in BotDetect v4.0 page.