How to Add BotDetect PHP CAPTCHA Protection to Symfony 2 Applications

Adding BotDetect PHP Captcha protection to your Symfony 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 Symfony2 Captcha Quickstart for key integration steps.

Prerequisites

Table of Contents

The BotDetect Symfony CAPTCHA Integration Package

Symfony is a MVC framework that leverages certain conventions to provide a rich set of functionality to PHP application developers. Therefore adding BotDetect Captcha into Symfony based site or application requires a layer of integration code to conform to those conventions. This enables BotDetect Captcha to integrate seamlessly and be used according to expectations of Symfony developers.

Path Aliases Used Throughout This Guide

For convenience purposes we are providing the BotDetect Captcha Symfony integration code packaged as a Symfony composer package.

You can get the whole BotDetect Symfony Captcha integration package here. The package contains the integration code, basic Captcha validation example, an contact form validation example. There is also an example of adding BotDetect Captcha into FOSUserBundle Login and Register forms.

The BotDetect Symfony CaptchaBundle

BotDetect Symfony CaptchaBundle is available at https://packagist.org/packages/captcha-com/symfony-captcha-bundle

The CaptchaBundle includes a wrapper class around the regular BotDetect Captcha Library for use in your application.

The CaptchaBundle also includes separate Controller that handles Captcha image, sound, and resources requests, which use
http://<MY_SYMFONY_WEBROOT>/web/simple-captcha-handler Urls by default.

Symfony Basic BotDetect CAPTCHA Example

This basic Symfony2 Captcha example shows how to use the CaptchaBundle in your form, and validate user input through the ValidSimpleCaptcha constraint in your entity.

  • Config: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples /app/config/botdetect.xml
  • Form Type: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Form/Type/BasicType.php
  • Entity: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Entity/Basic.php
  • Controller: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Controllers/BasicController.php
  • View: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Resources/views/Basic/basic.html.twig

Form Validation BotDetect Symfony CAPTCHA Example

This Symfony2 form validation Captcha example shows how to use the CaptchaBundle in form and validate user input through the ValidSimpleCaptcha constraint in your entity by implementing a simple contact form.

  • Config: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples /app/config/botdetect.xml
  • Form Type: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Form/Type/ContactType.php
  • Entity: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Entity/Contact.php
  • Controller: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Controllers/ContactController.php
  • View: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Resources/views/Contact/contact.html.twig

Symfony FOSUserBundle CAPTCHA Example

This Symfony2 FOSUserBundle CAPTCHA code example shows how to integrate CaptchaBundle into FOSUserBundle login and register forms.

  • Config: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples /app/config/botdetect.xml
  • Form Type: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Form/Type/RegistrationFormType.php
  • Entity: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Entity/User.php
  • View: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Resources/views/Security/login.html.twig
  • Controller: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src /AppBundle/Controllers/SecurityController.php
  • Bundle: <BD_SYMFONY_PACK>/bd-captcha-symfony2-examples/src AppBundle/AppBundle.php

Provided examples are available inside of a single Symfony app via their respective controllers:

http://<MY_SYMFONY_WEBROOT>/web/example
http://<MY_SYMFONY_WEBROOT>/web/contact
http://<MY_SYMFONY_WEBROOT>/web/login
http://<MY_SYMFONY_WEBROOT>/web/register

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

1. Include BotDetect CAPTCHA in Your Symfony MVC Application

Install the BotDetect Symfony CaptchaBundle

Note: If you do not have Composer yet, you can install it by following the instructions on https://getcomposer.org

If you have Git installed on your development machine, you should use the following installation procedure:

Step 1: Download CaptchaBundle using composer

Run the following command in your application's root directory:

Step 2: Enable the bundle (app/AppKernel.php):

$bundles = array(
  ...
  new Captcha\Bundle\CaptchaBundle\CaptchaBundle(),
);

Step 3: Import CaptchaBundle routing file (app/config/routing.yml):

captcha_routing:
  resource: "@CaptchaBundle/Resources/config/routing.yml"

2. Display BotDetect CAPTCHA in Your Symfony Form

Captcha configuration options

<?xml version="1.0" encoding="UTF-8"?>
<botdetect xmlns="https://captcha.com/schema/php"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/php
     https://captcha.com/schema/php/botdetect-4.2.3.xsd">

  <captchaStyles>
    <captchaStyle>
      <name>ExampleCaptcha</name>
      <userInputID>captchaCode</userInputID>
      <codeLength>3-5</codeLength>
    </captchaStyle>
  </captchaStyles>

</botdetect>

In order to use the CaptchaBundle, you must delare Captcha configuration in app/config/botdetect.xml file following the structure given above. The ExampleCaptcha is an example name and will be used as captcha field type, or to get a captcha object instance in some scenarios that you do not want to use captcha field type to display captcha in your form. You should pick a name that best matches your usage scenario like: LoginCaptcha, ContactCaptcha, etc. You can find a full list of available Captcha configuration options and related instructions at the Captcha configuration options page.

Compose Your Symfony Form With BotDetect CAPTCHA Display

namespace AppBundle\Form\Type;

// ...

class ExampleType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder->add('captchaCode', 'simple_captcha', array(
      'captchaStyleName' => 'Example'
    ));
  }

CaptchaBundle provides captcha field type to add Captcha in your forms. It is required to declare captchaStyleName option and assign it a captcha style name defined in app/config/botdetect.xml file.

3. Validate CAPTCHA In Your Symfony Entity

Validate the Submitted CAPTCHA Code User Input

namespace AppBundle\Entity;

use Captcha\Bundle\CaptchaBundle\Validator\Constraints as CaptchaAssert;

class Example
{
  /**
   * @CaptchaAssert\ValidSimpleCaptcha(
   *      message = "CAPTCHA validation failed, try again."
   * )
   */
  protected $captchaCode;

  public function getCaptchaCode()
  {
    return $this->captchaCode;
  }

  public function setCaptchaCode($captchaCode)
  {
    $this->captchaCode = $captchaCode;
  }
}

After Captcha is displayed in your form, you would want to validate the Captcha code user submitted. To do that, you should simply use the ValidSimpleCaptcha constraint in your entity that is available in the CaptchaBundle. You can also customize an error message by adding your custom error message to message option.

Handle CAPTCHA Validation Failure / Success

Symfony validation will abort further processing and display an error on failure, or proceed with a protected form action on success:

$form ->handleRequest($request);
if ($form->isValid()) {
  // TODO: Captcha validation passed:
  // continue with form processing, knowing the submission was made by a human
}

This ensures particular sensitive action to be executed only if a human filled the form.