Laravel 5.1 Form Validation BotDetect CAPTCHA Example (BotDetect v3.0; deprecated)

First Time Here?

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

Laravel Form Validation BotDetect CAPTCHA Example shows how to integrate BotDetect PHP Captcha validation and Laravel validation functionality. It uses Laravel's validation class

The brief example is based around a contact form which sends email if the user input is considered valid – a likely real world scenario for Captcha protection integration.

BotDetect Laravel 5.1 CAPTCHA Form Captcha validation screenshot

Files for this ('bd-captcha-laravel-5.1-examples') example are:

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

Routing – /app/Http/routes.php

Route::get('contact', 'ContactController@getContact');
Route::post('contact', 'ContactController@postContact');

In the code above we have registered HTTP GET and POST verbs for the contact page. On HTTP GET request to the contact page, the getContact() action of the ContactController is executed, while on a HTTP POST request to the example page, the postContact() action of the ContactController is executed.

View – /resources/views/contact.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel Form BotDetect CAPTCHA Example</title>
  <link href="{{ URL::asset('css/bootstrap.min.css') }}" type="text/css" 
  rel="stylesheet">
  
  <!-- include the BotDetect layout stylesheet -->
  <link href="{{ CaptchaUrls::LayoutStylesheetUrl() }}" type="text/css" 
  rel="stylesheet">
</head>
<body>
  <nav class="navbar navbar-default">
    <div class="container-fluid">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" 
        data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle Navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">BotDetect Captcha</a>
      </div>

      <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
        <ul class="nav navbar-nav navbar-right">
          <li><a href="{{ URL::to('example') }}">Basic Example</a></li>
          <li><a href="{{ URL::to('contact') }}">Form Example</a></li>
        </ul>
      </div>
    </div>
  </nav>

  <div class="container-fluid">
  <div class="row">
    <div class="col-md-8 col-md-offset-2">
      <div class="panel panel-default">
        <div class="panel-heading">Form Example</div>
        <div class="panel-body">

        @if (session('status'))
          <div class="alert alert-success">
            {{ session('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 class="form-horizontal" role="form" method="POST" 
        action="{{ URL::to('contact') }}">
          {!!csrf_field() !!}

            <div class="form-group">
              <label class="col-md-4 control-label">Name</label>
              <div class="col-md-6">
                <input type="text" class="form-control" name="name" 
                value="{{ old('name') }}">
              </div>
            </div>

            <div class="form-group">
              <label class="col-md-4 control-label">Email</label>
              <div class="col-md-6">
                <input type="text" class="form-control" name="email" 
                value="{{ old('email') }}">
              </div>
            </div>

            <div class="form-group">
              <label class="col-md-4 control-label">Subject</label>
              <div class="col-md-6">
                <input type="text" class="form-control" name="subject" 
                value="{{ old('subject') }}">
              </div>
            </div>

            <div class="form-group">
              <label class="col-md-4 control-label">Message</label>
              <div class="col-md-6">
                <textarea class="form-control" name="message">
                {{ old('message') }}</textarea>
              </div>
            </div>

            <div class="form-group">
              <div class="col-md-6 col-md-offset-4">
                <!-- Captcha image html-->
                {!! $captchaHtml !!}
              </div>
              <div class="col-md-6 col-md-offset-4">
                <!-- Captcha code user input textbox -->
                <input type="text" class="form-control" id="CaptchaCode" 
                 name="CaptchaCode" style="width: 276px; margin-top: 5px">
              </div>
            </div>

            <div class="form-group">
              <div class="col-md-6 col-md-offset-4">
                <button type="submit" class="btn btn-primary">
                  Submit
                </button>
              </div>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

  <!-- Scripts -->
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</body>
</html>

The View part of this example is straightforward. The above code uses the Laravel Blade syntax to generate Captcha image. The Captcha related Html is placed above the Captcha code form input field.

Controller – /app/Http/Controllers/ContactController.php

<?php namespace App\Http\Controllers;

use Validator;
use Illuminate\Http\Request;
// Importing the BotDetectCaptcha class
use LaravelCaptcha\Integration\BotDetectCaptcha;

class ContactController extends Controller 
{
  // get captcha instance to handle for the contact page
  private function getContactCaptchaInstance()
  {
    // Captcha parameters
    $captchaConfig = [
      'CaptchaId' => 'ContactCaptcha', // 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/ContactCaptchaConfig.php'
    ];
    return BotDetectCaptcha::GetCaptchaInstance($captchaConfig);
  }

  // get a validator for an incoming contact request.
  public function validator(array $data)
  {
    return Validator::make($data, [
      'name' => 'required|min:5',
      'email' => 'required|email',
      'subject' => 'required|min:10',
      'message' => 'required|min:20'
    ]);
  }
  
  public function getContact() 
  {
    // get contact captcha instance
    $captcha = $this->getContactCaptchaInstance();

    // passing Captcha Html to contact view
    return view('contact', ['captchaHtml' => $captcha->Html()]);
  }

  public function postContact(Request $request)
  {
    // get contact captcha instance
    $captcha = $this->getContactCaptchaInstance();

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

    $validator = $this->validator($request->all());

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

      return redirect()
                  ->back()
                  ->withInput()
                  ->withErrors($validator->errors());
    }

    // Captcha validation passed
    // TODO: send email

    return redirect()
                ->back()
                ->with('status', 'Your message was sent successfully.');
  }

}

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 5.1 integration guide.

After creating a function to get an instance of the Captcha class called getContactCaptchaInstance(), the getContact() action refers contact view and pass a Captcha Html to View by pass an array of data as the second parameter to the view helper on HTTP GET request.

On HTTP POST request (which occurs when user submits the form), the postContact() action is executed and this is where we validate the user's Captcha code input (using the Validation class) and validate Captcha Code using the Validate() method of the $captcha object.

Finally, we redirect user to contact page and pass some data to contact view.

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

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

// BotDetect PHP Captcha configuration options

$LBD_CaptchaConfig = CaptchaConfiguration::GetSettings();

$LBD_CaptchaConfig->CodeLength = CaptchaRandomization::GetRandomCodeLength(4, 6);

In the code above, we have overridden the default settings of library. 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.