Spread the love

Captcha is used to enhance the security of form. By adding the Captcha in laravel form we can prevent attackers to submit the form using the automated scripts and it adds an extra layer of security. To add the captcha in laravel form we can use package mews/captcha, its easy to use and also provide validation rule to validate the captcha.

mews/captcha gives multiple options to use and we can also configure it according to our need. Using the captcha package we can use it stateless and session mode means we can use it using laravel session and without the session , without session it uses a key in request to validate the captcha.

This package also provide the configure the math in captcha, length of captcha and expiry time of captcha therefore we can configure all these things in config file of it.

So let’s install or add captcha in laravel form with example

Captcha in laravel

Step 1 : Install the package

I assume the you have already installed the laravel and basic connection of it like database connection and composer.

Now install the package using composer in laravel root directory, open the terminal in laravel root directory and run below command

composer require mews/captcha

And then run composer update

composer update

Also make sure you have gd, file_info and mbstring extension are loaded

How to check a PHP extension is installed and enabled ?

To check whether a module is enables or not we can check in terminal by below command wil give you all installed php module

php -m

you can also check in php file

<?php 
      echo "<pre>";
      print_r(get_loaded_extensions());
      echo "<pre/>";
 ?>

Step 2 : Add Service provider and alias

Most of the packages comes with laravel package discovery enabled and automatic add service provider to packages built after laravel 5.5 so if your laravel version is greater then 5.5 then you can skip this step.

Search for providers key and Add service provider in config\app.php

'providers' => [
        // ...
        Mews\Captcha\CaptchaServiceProvider::class,,
    ]

Also find alias key and add as below

aliases' => [
        // ...
        'Captcha' => Mews\Captcha\Facades\Captcha::class,
    ]

Step 3 : Publish config to add configuration

Now, publish the config of package so we can change the config according to need. Run the below command in project directory

php artisan vendor:publish

this will create an file inconfig/captcha.php

return [
    'default'   => [
        'length'    => 5,
        'width'     => 120,
        'height'    => 36,
        'quality'   => 90,
        'math'      => true,  //Enable Math Captcha
        'expire'    => 60,    //Stateless/API captcha expiration
    ],
    // ...
];

Step 4 : Create routes

Add appropriate routes to connect our URL to controller therefore open routes/web.php and add below routes

<?php
use Illuminate\Support\Facades\Route;
use \App\Http\Controllers\PostController;


Route::get('/create-post',[PostController::class, 'create']);
Route::post('/submit-post',[PostController::class, 'store']);
Route::get('/refresh-captcha', [PostController::class, 'refreshCaptcha']);

Here we created three routes one create-post to show the form, submit-post to submit the form and refresh-captcha to refresh captcha again.

Step 4 : Create Controller

Now, create the controller as we have mentioned in routes is PostController and also create three methods create, store and refreshCaptcha so create a file in app\Http\Controllers\PostController.php

<?php

namespace App\Http\Controllers;

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


class PostController extends Controller
{

    public function create()
    {
        return view('post.create-post');
    }

    public function store(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            [
                'email' => 'required|email',   // required and email format validation
                'phone_number' => 'required|numeric|digits_between:9,15', // required and number field validation
                'username' => ['required'],
                'password' => 'required',
                'password_confirmation' => 'required|same:password',
                'captcha' => 'required|captcha'

            ],
            ['captcha.captcha' => 'Enter valid captcha code shown in image']
        ); // create the validations

        if ($validator->fails())   //check all validations are fine, if not then redirect and show error messages
        {
            return back()->withInput()->withErrors($validator);
        } else {
            return response()->json(["status" => true, "message" => "Form submitted successfully"]);
        }
    }
    public function refreshCaptcha()
    {
        return response()->json(['captcha' => captcha_img()]);
    }
}

as you can see we have added the validation for captcha here

  $validator = Validator::make($request->all(), [
            ....
            'captcha' => 'required|captcha'

        ],['captcha.captcha' => 'Enter valid captcha code shown in image']); // create the validations

and to refresh the captcha we used refreshCaptcha method.

Step 5 : Create view

We have create the controller and logic for validate the captcha now its time to show the captcha in form and submit to store method hence here is our view

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Readerstacks add captcha, refresh captcha and validate example in laravel</title>

  <link href="//netdna.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>

<body class="antialiased">
  <div class="container">
    <!-- main app container -->
    <div class="readersack">
      <div class="container">
        <div class="row">
          <div class="col-md-6 offset-md-3">
            <h3> Add captcha, refresh captcha and validate example in laravel - Readerstacks</h3>

            <form method="post" id="validateajax" action="{{url('submit-post')}}" name="registerform">
              <div class="form-group">
                <label>Email</label>
                <input type="text" name="email" value="{{ old('email') }}" class="@error('email') is-invalid @enderror form-control" />

                @error('email')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
                @csrf
              </div>
              <div class="form-group">
                <label>Phone number</label>
                <input type="text" name="phone_number" value="{{ old('phone_number') }}" class="@error('phone_number') is-invalid @enderror form-control" />
                @error('phone_number')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
              </div>
              <div class="form-group">
                <label>Username</label>
                <input type="text" name="username" value="{{ old('username') }}" class="@error('username') is-invalid @enderror form-control" />
                @error('username')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
              </div>
              <div class="form-group">
                <label>Password</label>
                <input type="password" name="password" class="@error('password') is-invalid @enderror form-control" />
                @error('password')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
              </div>
              <div class="form-group">
                <label>Confirm Password</label>
                <input type="password" name="password_confirmation" class="@error('password_confirmation') is-invalid @enderror form-control" />
                @error('password_confirmation')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
              </div>
              <div class="form-group">
                <label for="capatcha">Captcha</label>
                <div class="captcha">
                  <span>{!! captcha_img() !!}</span>
                  <button type="button" class="btn btn-success refresh-cpatcha"><i class="fa fa-refresh"></i></button>
                </div>
                <input id="captcha" type="text" class="form-control" placeholder="Enter Captcha" name="captcha">
                @error('captcha')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
              </div>
              <div class="form-group">
                <button class="btn btn-primary">Register</button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
    <!-- credits -->
    <div class="text-center">
      <p>
        <a href="#" target="_top">Add captcha, refresh captcha and validate example in laravel - Readerstacks</a>
      </p>
      <p>
        <a href="https://readerstacks.com" target="_top">readerstacks.com</a>
      </p>
    </div>
  </div>
</body>

<script type="text/javascript">
  $(".refresh-cpatcha").click(function() {
    $.ajax({
      type: 'GET',
      url: "{{url('refresh-captcha')}}",
      success: function(data) {
        $(".captcha span").html(data.captcha);
      }
    });
  });
</script>

</html>

Here, we used {!! captcha_img() !!} to show the captcha and @error('captcha') to show the validations

 <div class="form-group">
                <label for="capatcha">Captcha</label>
                <div class="captcha">
                  <span>{!! captcha_img() !!}</span>
                  <button type="button" class="btn btn-success refresh-cpatcha"><i class="fa fa-refresh"></i></button>
                </div>
                <input id="captcha" type="text" class="form-control" placeholder="Enter Captcha" name="captcha">

                @error('captcha')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
  </div>

and to show the refresh button we used this script

<script type="text/javascript">
  $(".refresh-cpatcha").click(function() {
    $.ajax({
      type: 'GET',
      url: "{{url('refresh-captcha')}}",
      success: function(data) {
        $(".captcha span").html(data.captcha);
      }
    });
  });
</script>

Now serve the project using

php artisan serve

and check the implementation.

Screenshot :

Leave a Reply