Laravel 4.2 Auth CAPTCHA Example (BotDetect v3.0; deprecated)

Laravel Auth CAPTCHA Example demonstrates how to integrate BotDetect PHP Captcha into login and register forms in a scenario where Laravel Auth is used to authenticate users to your application.

First Time Here?

Check the BotDetect Laravel 4.2 Captcha Quickstart for key integration steps.

Alongside the Captcha image, the user is provided with an input field to retype the displayed characters. Depending on if the Captcha code entered matches the displayed one or not, a message stating the validation result is shown on the form.

The simple code showing the message in this example would of course be replaced with useful form processing code in a real world scenario.

We have used Forms & HTML to generate a form, Validation class to validate input fields data, and Blade Templating.

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

Next, we need to create users table -- using Migrations. We have prepared a create-users-table migration which is located at: app/database/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 Laravel integration package.

Routing – /app/routes.php

Route::controller('users', 'UsersController');

In the code above we use the Implicit Controllers to define a single route which will handle every user action in the UsersController.

View – /app/views/layouts/master.blade.php

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Laravel Authentication</title>
  {{ HTML::style('css/bootstrap.min.css') }}
  
  <!-- include the BotDetect layout stylesheet -->
  {{ HTML::style(CaptchaUrls::LayoutStylesheetUrl()) }}

  <style type="text/css">
    body { padding: 70px 0 }
    .container{ width: 980px !important }
    .error { color: red }
  </style>
</head>
<body>
  <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">BotDetect Captcha</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
            <!-- Determining if a user is authenticated -->
            @if (Auth::check())
              <li>{{ HTML::link('users/logout', 'Logout') }}</li>   
            @else
              <li>{{ HTML::link('users/register', 'Register') }}</li>   
              <li>{{ HTML::link('users/login', 'Login') }}</li>  
            @endif
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">
         @yield('content')
    </div>
</body>
</html>

The above code is defining a Blade Layout. We have added required stylesheet using the HTML::style() method. Checking whether the user is logged in or not we did with Auth::check() method.

View – /app/views/users/login.blade.php

@extends('layouts.master')

@section('content')

    <h2>Login</h2><hr>

    @if (Session::has('status'))
      <div class="alert alert-success">
        {{ Session::get('status') }}
      </div>
    @endif

    @if (count($errors) > 0)
      <div class="alert alert-danger">
        <strong>Whoops!</strong> There were some problems with your input.<br><br>
        <ul>
          @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
          @endforeach
        </ul>
      </div>
    @endif

    {{ Form::open(array('url' => 'users/login')) }}

    <div class="form-group">
        {{ Form::label('inputEmail', 'Email') }}
        {{ Form::text('email', Input::old('email'), array(
                'id' => 'inputEmail',
                'class' => 'form-control'
            ))
        }}
    </div>

    <div class="form-group">
        {{ Form::label('inputPassword', 'Password') }}

        {{ Form::password('password', array(
                'id' => 'inputPassword',
                'class' => 'form-control'
            ))  
        }}
    </div>

    <div class="form-group">
        <!-- Captcha image html-->
        {{ $captchaHtml }}
    </div>

    <div class="row">
        <div class="form-group col-sm-4">
            {{ Form::label('CaptchaCode', 'Retype the characters from the picture') }}

            <!-- Captcha code user input textbox -->
            {{ Form::text('CaptchaCode', null, array(
                    'id' => 'CaptchaCode',
                    'class' => 'form-control'
                ))
            }}
        </div>
    </div>

    <div class="checkbox">
        <label>{{ Form::checkbox('remember_me', null) }} Remember me</label>
    </div>

    {{ Form::submit('Login', array('class' => 'btn btn-primary')) }}    
{{ Form::close() }}

@stop

The above code is used to generate a form using the Forms & HTML and the Blade syntax. To display authentication in a view, we output the variable $captchaHtml (set in, and passed by in the getLogin() action of the UsersController).

We have added Captcha Code input field to view. This Captcha Code input will be checked in the postLogin() action later.

Login page screenshot:

Laravel 4.2 Auth Login BotDetect Captcha validation screenshot

View – /app/views/users/register.blade.php

@extends('layouts.master')

@section('content')

    <h2>Register now</h2><hr>

    @if (Session::has('status'))
      <div class="alert alert-success">
        {{ Session::get('status') }}
      </div>
    @endif

    @if (count($errors) > 0)
      <div class="alert alert-danger">
        <strong>Whoops!</strong> There were some problems with your input.<br><br>
        <ul>
          @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
          @endforeach
        </ul>
      </div>
    @endif

    {{ Form::open(array('url' => 'users/register')) }}

    <div class="form-group">
        {{ Form::label('inputName', 'Name') }}
        {{ Form::text('name', Input::old('name'), array(
                'id' => 'inputName',
                'class' => 'form-control'
            ))
        }}
    </div>

    <div class="form-group">
        {{ Form::label('inputEmail', 'Email') }}
        {{ Form::text('email', Input::old('email'), array(
                'id' => 'inputEmail',
                'class' => 'form-control'
            ))
        }}
    </div>

    <div class="form-group">
        {{ Form::label('inputPassword', 'Password') }}

        {{ Form::password('password', array(
                'id' => 'inputPassword',
                'class' => 'form-control'
            ))  
        }}
    </div>

    <div class="form-group">
        {{ Form::label('inputPasswordConfirmation', 'Confirm Password') }}

        {{ Form::password('password_confirmation', array(
                'id' => 'inputPasswordConfirmation',
                'class' => 'form-control'
            ))  
        }}
    </div>

    <div class="form-group">
        <!-- Captcha image html-->
        {{ $captchaHtml }}
    </div>

    <div class="row">
        <div class="form-group col-sm-4">
            {{ Form::label('CaptchaCode', 'Retype the characters from the picture') }}

            <!-- Captcha code user input textbox -->
            {{ Form::text('CaptchaCode', null, array(
                    'id' => 'CaptchaCode',
                    'class' => 'form-control'
                ))
            }}
        </div>
    </div>

    {{ Form::submit('Register', array('class' => 'btn btn-primary')) }}     
{{ Form::close() }}

@stop

The above code is used to generate a form using the Forms & HTML and the Blade syntax. To display authentication in a view, we output the variable $captchaHtml (set in, and passed by in the getRegister() action of the UsersController).

We also added Captcha Code input field to view. This Captcha Code input will be checked in the postRegister() action later.

Register page screenshot:

Laravel 4.2 Auth Register BotDetect Captcha validation screenshot

View – /app/views/users/dashboard.blade.php

@extends('layouts.master')

@section('content')
  <h2>Dashboard</h2><hr>
  Welcome <strong>{{ Auth::user()->name }}</strong>. You have logged in your system.
@stop

The code above displays the logged-in user's name using the Auth::user() method.

Controller – /app/controllers/UsersController.php

<?php

// Importing the BotDetectCaptcha class
use LaravelCaptcha\Integration\BotDetectCaptcha;

class UsersController extends BaseController {

  protected $layout = 'layouts.master';

  // get a 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 controllers folder
      'CaptchaConfigFilePath' => 'captcha_config/RegisterCaptchaConfig.php', 
    ];
    $captcha = BotDetectCaptcha::GetCaptchaInstance($captchaConfig);

    return $captcha;
  }

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

    // passsing Captcha Html to register view
    $this->layout->content = View::make('users.register', array('captchaHtml' => $captcha->Html()));
  }

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

    // validate the user-entered Captcha code when the form is submitted
    $code = Input::get('CaptchaCode');
    $isHuman = $captcha->Validate($code);

      $validator  = Validator::make(Input::all(), array(
            'name' => array('required', 'alpha', 'min:5'),
            'email' => array('required', 'email', 'unique:users'),
            'password' => array('required', 'between:6,30', 'confirmed'),
            'password_confirmation' => array('required', 'between:6,30')
        )
      );

      if (!$isHuman || $validator->fails()) 
      {
        if (!$isHuman)
        {
           $validator->errors()->add('CaptchaCode', 'Wrong code. Try again please.');
        }

        return Redirect::to('users/register')
                              ->withInput()
                              ->withErrors($validator->errors());
      }

      // Captcha validation passed
      // Save new user
      $user = new User;
      $user->name = Input::get('name');
      $user->email = Input::get('email');
      $user->password = Hash::make(Input::get('password'));
      $user->save();
      
      return Redirect::to('users/register')
                          ->with('status', 'Thank you. You have successfully registerd.');
  }

  // get a 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
      // path of the Captcha config file inside your controllers folder
      'CaptchaConfigFilePath' => 'captcha_config/LoginCaptchaConfig.php', 
    ];
    $captcha = BotDetectCaptcha::GetCaptchaInstance($captchaConfig);

    return $captcha;
  }

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

    // passing Captcha Html to login view
    $this->layout->content = View::make('users.login', array('captchaHtml' => $captcha->Html()));                 
  }

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

    // validate the user-entered Captcha code when the form is submitted
    $code = Input::get('CaptchaCode');
    $isHuman = $captcha->Validate($code);

    $rememberMe = (Input::get('remember_me') == 'on') ? true : false;
    $errorMessages = array();

    if ($isHuman) 
    {
      if (Auth::attempt(array('email' => Input::get('email'), 'password' => Input::get('password')), $rememberMe)) 
      {
        return Redirect::to('users/dashboard');
      }
      else
      {
        $errorMessages = array('email' => 'The email or password you entered is incorrect, please try again.');
      }
    }
    else
    {
      $errorMessages = ['CaptchaCode' => 'Wrong code. Try again please.'];
    }

    return Redirect::to('users/login')
            ->withInput(Input::except('password'))
            ->withErrors($errorMessages);
  }

  public function getDashboard() {
      $this->layout->content = View::make('users.dashboard');
  }

  public function getLogout() {
      Auth::logout();
      return Redirect::to('users/login');
  }

  
}

The Controller part of the example provides necessary helpers and data used by View, and adds the Captcha validation functionality as outlined in the BotDetect Laravel 4.2 integration guide.

After creating two functions to get an instance of the Captcha class for each page called getRegisterCaptchaInstance() and getLoginCaptchaInstance(), on a HTTP GET request the getRegister(), and the getLogin() actions pass the generated Captcha Html to View by pass an array of data as the second parameter to the view helper (or you can also use the with() method).

Method: postRegister()

On HTTP POST request (user submit), the postRegister() action executes and we validate user entered data using the Validation class and validate Captcha Code with the Validate() method of the $captcha object.

Method: postLogin()

On HTTP POST request (user submit), the postLogin() action executes and we check user's email and password using the Auth::attempt() and validate Captcha Code with the Validate() method of the $captcha object.

Filters – /app/filters.php

Route::filter('auth', function()
{
  if (Auth::guest())
  {
    if (Request::ajax())
    {
      return Response::make('Unauthorized', 401);
    }
    else
    {
      // Redirect to the users/login page 
      return Redirect::guest('users/login');
    }
  }
});

In code above we have modified the auth filter to redirect all non-authenticated users to users/login page.

Captcha configuration options – /app/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 – /app/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.