CakePHP 3.0 Auth CAPTCHA Example (BotDetect v3.0; deprecated)

This example demonstrates how to integrate BotDetect PHP Captcha into login and register forms in a scenario where CakePHP Auth Component is used to authenticate users to your application.

First Time Here?

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

When CakePHP Auth Component is turned on in your application, it requires you to use database. Here is how to create it:

First, we need to configure database connection with entering connection details into the <MY_CAKE_WEBROOT>/config/app.php file.

Next, we need to create users table -- using Migrations. We have prepared a create_users migration which is located at: <MY_CAKE_WEBROOT>/config/Migrations/

To create users table, run the following command in your application's root directory:

Files for this example are:

The files are available for download as a part of the BotDetect Captcha CakePHP integration package.

View – /src/Template/Users/login.ctp

<!-- include the BotDetect layout stylesheet -->
<?= $this->Html->css(CaptchaUrls::LayoutStylesheetUrl(), ['inline' => false]) ?>

<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __('Please enter your username and password') ?></legend>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('password') ?>

        <!-- show captcha image -->
        <?= $captchaHtml ?>

    <!-- Captcha code user input textbox -->
    <?= $this->Form->input('CaptchaCode', [
      'label' => 'Retype the characters from the picture:',
      'maxlength' => '10',
      'id' => 'CaptchaCode'
    ]) ?>
    </fieldset>


<?= $this->Form->button(__('Login'), ['style' => 'float: left']) ?>
<?= $this->Form->end() ?>
</div>

The above code is used to create CakePHP FormHelper. To display authentication in a view, we output the variable $captchaHtml (set in, and passed by in the login() method of UsersController).

Also we have added Captcha Code input field to view. This Captcha Code input will be checked in the login() method later.

To display correctly, BotDetect Captcha PHP requires you to include its CSS. We have used HtmlHelper::css() to create a link to the CSS file.

Login page screenshot:

CakePHP 3.0 Auth Login BotDetect Captcha validation screenshot

View – /src/Template/Users/register.ctp

<!-- include the BotDetect layout stylesheet -->
<?= $this->Html->css(CaptchaUrls::LayoutStylesheetUrl(), ['inline' => false]) ?>

<div class="users form">
<?= $this->Form->create($user) ?>
    <fieldset>
        <legend><?= __('Register User') ?></legend>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('email') ?>
        <?= $this->Form->input('password') ?>
        <?= $this->Form->input('confirm_password', ['type' => 'password']) ?>

        <!-- show captcha image -->
    <?= $captchaHtml ?>

        <!-- Captcha code user input textbox -->
    <?= $this->Form->input('CaptchaCode', [
      'label' => 'Retype the characters from the picture:',
      'maxlength' => '10',
      'id' => 'CaptchaCode'
    ]) ?>
   </fieldset>
<?= $this->Form->button(__('Register'), ['style' => 'float: left']) ?>
<?= $this->Form->end() ?>
</div>

The above code is used to create CakePHP FormHelper. To display authentication in a view, we output the variable $captchaHtml (set in, and passed by in the register() method of UsersController).

Also we have added Captcha Code input field to view. This Capthca Code input will be checked in the register() method later.

To display correctly, BotDetect Captcha PHP requires you to include its CSS. We have used HtmlHelper::css() to create a link to the CSS file.

Register page screenshot:

CakePHP 3.0 Auth Register BotDetect Captcha validation screenshot

Controller – /src/Controller/UsersController.php

<?php namespace App\Controller;

use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Network\Exception\NotFoundException;
// Importing the BotDetectCaptcha class
use CakeCaptcha\Integration\BotDetectCaptcha;

class UsersController extends AppController
{
    public $layout = 'auth';

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        // Allow users to register and logout.
        $this->Auth->allow(['register', 'logout']);
    }


    // get captcha instance to handle for the login page
    private function getLoginCaptchaInstance() {
        // Captcha parameters
        $captchaConfig = [
          'CaptchaId' => 'LoginCaptcha', // a unique Id for the Captcha instance
          'UserInputId' => 'CaptchaCode', // Id of the Captcha code input textbox
          // The path of the Captcha config file is inside the config folder
          'CaptchaConfigFilePath' => 'captcha_config/LoginCaptchaConfig.php',
        ];
        return BotDetectCaptcha::GetCaptchaInstance($captchaConfig);
    }

    public function login()
    {
        // captcha instance of the login page
        $captcha = $this->getLoginCaptchaInstance();

        // passing Captcha Html to example view
        $this->set('captchaHtml', $captcha->Html());

        if ($this->request->is('post')) {

            // validate the user-entered Captcha code
            $isHuman = $captcha->Validate($this->request->data['CaptchaCode']);

            // clear previous user input, since each Captcha code can only be validated once
            unset($this->request->data['CaptchaCode']);
            
            if ($isHuman) {
                $user = $this->Auth->identify();
                if ($user) {
                    $this->Auth->setUser($user);
                    return $this->redirect($this->Auth->redirectUrl());
                }
                $this->Flash->error(__('Invalid username or password, try again'));
            } else {
                $this->Flash->error(__('CAPTCHA validation failed, try again.'));
            }
        }
    }

    // get captcha instance to handle for the register page
    private function getRegisterCaptchaInstance() {
        // Captcha parameters
        $captchaConfig = [
          'CaptchaId' => 'RegisterCaptcha', // a unique Id for the Captcha instance
          'UserInputId' => 'CaptchaCode', // Id of the Captcha code input textbox
          // path of the Captcha config file inside your config folder
          'CaptchaConfigFilePath' => 'captcha_config/RegisterCaptchaConfig.php', 
        ];
        return BotDetectCaptcha::GetCaptchaInstance($captchaConfig);
    }

    public function register()
    {
        // captcha instance of the register page
        $captcha = $this->getRegisterCaptchaInstance();

        // passing Captcha Html to example view
        $this->set('captchaHtml', $captcha->Html());

        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {

            // validate the user-entered Captcha code
            $isHuman = $captcha->Validate($this->request->data['CaptchaCode']);

            // clear previous user input, since each Captcha code can only be validated once
            unset($this->request->data['CaptchaCode']);

            if ($isHuman) {
                $query = $this->Users->findAllByUsernameOrEmail($this->request->data['username'], $this->request->data['email']);
                if ($query->count() == 0) {
                    $user = $this->Users->patchEntity($user, $this->request->data);
                    if ($this->Users->save($user)) {
                        $this->Flash->success(__('The user has been saved.'));
                        return $this->redirect(['action' => 'register']);
                    }
                    $this->Flash->error(__('Unable to add the user.'));
                } else {
                    $this->Flash->error(__('This user already exists.'));
                }
            } else {
                 $this->Flash->error(__('CAPTCHA validation failed, try again.'));
            }
                
        }
        $this->set('user', $user);
    }

    public function logout()
    {
        return $this->redirect($this->Auth->logout());
    }

    public function index(){}
}

The example Controller follows the basic instructions from the BotDetect CakePHP 3.0 integration guide.

We need to create two functions to get an instance of the Captcha class for the login and register page, called getRegisterCaptchaInstance() and getLoginCaptchaInstance()

Method: login()

The Html required for displaying the Captcha image and integrated controls is made available to the View by using the Controller:set() method.

The example form submits data to the same Controller action that shows it (login). This is where we check the submitted captcha code and pass it to the Validate() method of the $captcha object.

Method: register()

The Html required for displaying the Captcha image and integrated controls is made available to the View by using the Controller:set() method.

The example form submits data to the same Controller action that shows it (register). This is where we check the submitted captcha code and pass it to the Validate() method of the $captcha object.

Captcha configuration options – /config/captcha_config/LoginCaptchaConfig.php

<?php if (!class_exists('CaptchaConfiguration')) { return; }

// BotDetect PHP Captcha configuration options

$LBD_CaptchaConfig = CaptchaConfiguration::GetSettings();

$imageStyles = array(
  ImageStyle::Chipped, 
  ImageStyle::Negative, 
);

$LBD_CaptchaConfig->ImageStyle =
                         CaptchaRandomization::GetRandomImageStyle($imageStyles);

In the code above, we have overridden the default settings of library for the login page. You can find a full list of available Captcha configuration options and related instructions at the Captcha configuration options page.

Captcha configuration options – /config/captcha_config/RegisterCaptchaConfig.php

<?php if (!class_exists('CaptchaConfiguration')) { return; }

// BotDetect PHP Captcha configuration options

$LBD_CaptchaConfig = CaptchaConfiguration::GetSettings();

$LBD_CaptchaConfig->CodeLength = 6;
$LBD_CaptchaConfig->ImageWidth = 250;
$LBD_CaptchaConfig->ImageHeight = 50;

In the code above, we have overridden the default settings of library for the register page. You can find a full list of available Captcha configuration options and related instructions at the Captcha configuration options page.



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.