Laravel 8 – 13
PHP 8.0+
The project is in a healthy, maintained state
A modern, highly customizable, and secure captcha package for Laravel.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

mockery/mockery
^1.6
phpunit/phpunit
^11.0|^12.0

Runtime

^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
 Project Readme

Laravel Captcha

Latest Version on Packagist Total Downloads License

A modern, highly customizable, secure, and high-performance captcha package for Laravel.

This package provides an easy way to protect your web forms from bots by generating image-based captchas. It's designed to be both user-friendly for humans and challenging for bots.


Features

  • Laravel 13 & PHP 8.2+ Ready: Fully compatible with Laravel 13 and leverages PHP 8.2+ capabilities (strict types, constructor promotion, native types).
  • 🚀 High Performance: Replaced slow bcrypt hashing key generation with a fast, secure, random token identifier (Str::random(40)), eliminating CPU hashing bottlenecks during page loads.
  • Intervention Image v3 Integration: Uses the latest version of the Intervention Image library with Gd driver support.
  • 🎨 Highly Customizable: Control everything from image dimensions and colors to character sets, custom fonts, backgrounds, and distortion levels.
  • 🛡️ Secure: Prevents replay attacks with one-time use keys, short cache expiration times, and optional encrypted client keys.
  • 🔌 Seamless Laravel Integration: Includes a Service Provider, Facade, and custom Validation Rule for effortless implementation.
  • 🌐 Multi-language Support: Translation files for validation messages are included out of the box.

Installation

You can install the package via Composer:

composer require mydaniel/laravel-captcha

Local Development (Path Repository)

If you are developing this package locally inside a packages/laravel-captcha directory, add it to your root composer.json repositories block:

"repositories": [
    {
        "type": "path",
        "url": "packages/laravel-captcha",
        "options": {
            "symlink": true
        }
    }
]

Then require it:

composer require mydaniel/laravel-captcha:"*"

Configuration

  1. Publish the configuration and translation files using the Artisan command:

    php artisan vendor:publish --provider="MyDaniel\Captcha\CaptchaServiceProvider"
  2. This will create two new files:

    • config/captcha.php: Configure all aspects of the captcha (e.g. dimensions, character sets, image styles, and drivers) under profiles like default, math, flat, and inverse.
    • lang/vendor/captcha/: Houses localization files for validation messages.

Usage

1. Displaying the Captcha

In your Blade view, use the Captcha::create() facade to generate the captcha data:

@php
    $captcha = \MyDaniel\Captcha\Facades\Captcha::create('default'); // Or 'math', 'flat', 'inverse', etc.
@endphp

<div class="form-group">
    {{-- Display the captcha image (Base64 data URI) --}}
    <img src="{{ $captcha['image'] }}" alt="Captcha Image">

    {{-- Input for the user to type the captcha code --}}
    <input type="text" id="captcha_code" name="captcha_code" required>

    {{-- Hidden field to store the captcha key identifier --}}
    <input type="hidden" name="captcha_key" value="{{ $captcha['key'] }}">
</div>

@error('captcha_code')
    <span class="text-danger">{{ $message }}</span>
@enderror

2. Validating the Input

In your controller or form request, validate using the custom Captcha rule.

Using the Validation Rule Object (Recommended)

This method is clean and type-safe:

use Illuminate\Http\Request;
use MyDaniel\Captcha\Rules\Captcha;

public function submitForm(Request $request)
{
    $request->validate([
        'captcha_code' => ['required', new Captcha($request->input('captcha_key'), 'default')],
        'captcha_key' => 'required|string',
    ]);

    // Validation passed, proceed...
}

Using the String-based Rule

You can also use the validator extension string alias:

use Illuminate\Http\Request;

public function submitForm(Request $request)
{
    $request->validate([
        'captcha_code' => 'required|captcha:' . $request->input('captcha_key') . ',default',
        'captcha_key' => 'required|string',
    ]);

    // Validation passed, proceed...
}

Testing

The package features a comprehensive test suite covering generators, the orchestrator, custom validation rules, and base64 image generation.

To run the package tests independently, install development dependencies inside the package directory:

composer install --working-dir=packages/laravel-captcha

Then run PHPUnit using the package's configuration:

./packages/laravel-captcha/vendor/bin/phpunit --configuration packages/laravel-captcha/phpunit.xml

Extensibility

Creating a New Generator

To create a new captcha type (e.g., a question-based captcha):

  1. Create a class that implements the \MyDaniel\Captcha\Contracts\CaptchaGeneratorContract interface:

    namespace App\Captcha;
    
    use MyDaniel\Captcha\Contracts\CaptchaGeneratorContract;
    
    class QuestionGenerator implements CaptchaGeneratorContract
    {
        public function generate(array $config): array
        {
            return [
                'text' => 'What is the capital of France?',
                'key'  => 'paris',
            ];
        }
    }
  2. Register your custom generator in a service provider:

    public function register()
    {
        $this->app->bind('captcha.generator.question', \App\Captcha\QuestionGenerator::class);
    }
  3. Reference your new generator driver in a profile inside config/captcha.php:

    'profiles' => [
        'question' => [
            'driver' => 'question',
            'expire' => 120,
        ]
    ]

License

This package is open-source software licensed under the MIT license.