Laravel 5.0 Form Validation BotDetect CAPTCHA Example

First Time Here?

Check the BotDetect Laravel 5.0 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.0 CAPTCHA Form Captcha validation screenshot

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

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.

Config – /config/captcha.php

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

// BotDetect PHP Captcha configuration options

return [
  // Captcha configuration for contact page
  'ContactCaptcha' => [
    'UserInputID' => 'CaptchaCode',
    'CodeLength' => CaptchaRandomization::GetRandomCodeLength(4, 6),
    'ImageStyle' => ImageStyle::AncientMosaic,
  ],

];

In order to use the Laravel CAPTCHA Package, we have declared Captcha configuration which will be used when showing Captcha image in contact view. Detailed description of this approach is available in a BotDetect Laravel 5.0 integration guide.

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="{{ captcha_layout_stylesheet_url() }}" 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') }}">
            <input type="hidden" name="_token" value="{{ csrf_token() }}">

            <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">
                <!-- Show captcha image html-->
                {!! captcha_image_html('ContactCaptcha') !!}
              </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 captcha_image_html() helper function to generate Captcha image. It is required to pass a captcha configuration key defined in config/captcha.php file.

The View needs to add the required stylesheet of the library by calling captcha_layout_stylesheet_url() helper function.

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

<?php namespace App\Http\Controllers;

use Illuminate\Support\Facades\Request;
use Validator;

class ContactController extends Controller
{
  public function getContact()
  {
    return view('contact');
  }

  public function postContact()
  {
    // custom error message for valid_captcha validation rule
    $messages  = [
      'valid_captcha' => 'Wrong code. Try again please.'
    ];

    $validator  = Validator::make(Request::all(), [
      'name' => 'required|min:5',
      'email'    => 'required|email',
      'subject' => 'required|min:10',
      'message' => 'required|min:20',
      'CaptchaCode' => 'required|valid_captcha'
    ], $messages);

    if ($validator->fails())
    {
      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.0 integration guide.

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 by using the valid_captcha validation rule.

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