Laravel 9 Captcha Tutorial: How to Add Captcha in Laravel

Throughout this tutorial, you will be taught how to add Captcha security in the Laravel application for implementing an extra layer of security for spam protection.

CAPTCHA is a simple test displayed on the web page; It stands for Completely Automated Public Turing test.

It is a diverse set of words, usually words and numbers. A user has to type the same words or numbers in the captcha input box to prove that he/she is a real user.

In this Laravel Captcha example, you will also learn how to use the mews/captcha package to prevent comment spam or fake registrations in Laravel, so get started to add captcha security in the Laravel application.

Laravel Project Installation

In the beginning, you have to run the command to commence the laravel project installation:

composer create-project laravel/laravel --prefer-dist laravel-add-captcha-example

Install Mews Captcha Package

You need to install the mewebstudio/captcha library that supports the Captcha for Laravel 5/6/7/8 version simultaneously.

composer require mews/captcha

Register Captcha in Laravel

To use the mews captcha library you have to inject it within the providers and aliases arrays in providers/config/app.php file:

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

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

    ]

Next, you need to publish the captcha file specifically; use the following command:

php artisan vendor:publish

On your console window, you will have a list of items; you have to choose “Mews\Captcha\CaptchaServiceProvider”. It will create a config/captcha.php file, here you can configure captcha settings:

<?php

return [
    ...
    'default' => [
        'length' => 9,
        'width' => 120,
        'height' => 36,
        'quality' => 90,
        'math' => true,
        'expire' => 60,
        'encrypt' => false,
    ],
...
...

Setting Up Controller

Create a new controller file that will handle the captcha programmatically:

php artisan make:controller FormController

Put code in app/Http/Controllers/FormController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormController extends Controller
{
    public function index()
    {
        return view('welcome');
    }

    public function createForm(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'email' => 'required|email',
            'username' => 'required',
            'captcha' => 'required|captcha'
        ]);
    }

    public function refreshCaptcha()
    {
        return response()->json(['captcha'=> captcha_img()]);
    }
}

Add Routes

Head over to routes/web.php file, import form controller over and above that define a couple of routes:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FormController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', [FormController::class, 'index']);
Route::post('/form', [FormController::class, 'createForm']);
Route::get('/refresh-captcha', [FormController::class, 'refreshCaptcha']);

Create Blade View

In this step, you will have to add the following code in resources/views/welcome.blade.php to manifest the captcha form 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>Laravel</title>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <style>
        .container {
            max-width: 600px;
        }
        .reload {
            font-family: Lucida Sans Unicode
        }
    </style>
</head>

<body>
    <div class="container mt-4">
        <h2>Laravel 8 Captcha Integration Example</h2>

        @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div><br />
        @endif
        <form method="post" action="{{url('form')}}">
            @csrf

            <div class="form-group">
                <label>Name</label>
                <input type="text" class="form-control" name="name">
            </div>

            <div class="form-group">
                <label>Email</label>
                <input type="text" class="form-control" name="email">
            </div>

            <div class="form-group">
                <label for="Password">User name</label>
                <input type="text" class="form-control" name="username">
            </div>

            <div class="form-group mt-3 mb-3">
                <div class="captcha">
                    <span>{!! captcha_img() !!}</span>
                    <button type="button" class="btn btn-danger" class="refresh-captcha" id="refresh-captcha">
                        &#x21bb;
                    </button>
                </div>
            </div>

            <div class="form-group mb-4">
                <input id="captcha" type="text" class="form-control" placeholder="Enter Captcha" name="captcha">
            </div>

            <div class="form-group">
                <button type="submit" class="btn btn-primary btn-block">Send</button>
            </div>
        </form>
    </div>
</body>

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

</script>

</html>

Next, start the project:

php artisan serve
http://127.0.0.1:8000

Laravel Captcha Example Tutorial

The Laravel Captcha tutorial is over, Thats it for, hope it will help you in learning laravel web development.