mydaniel / laravel-captcha
A modern, highly customizable, and secure captcha package for Laravel.
Package info
github.com/daniyousefifar/laravel-captcha
Type:laravel-package
pkg:composer/mydaniel/laravel-captcha
Requires
- php: ^8.0|^8.1|^8.2|^8.3|^8.4|^8.5
- ext-gd: *
- illuminate/config: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/filesystem: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/hashing: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- intervention/image: ^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^10.0
- phpunit/phpunit: ^11.0|^12.0
This package is auto-updated.
Last update: 2026-07-12 16:43:47 UTC
README
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
-
Publish the configuration and translation files using the Artisan command:
php artisan vendor:publish --provider="MyDaniel\Captcha\CaptchaServiceProvider" -
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 likedefault,math,flat, andinverse.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):
-
Create a class that implements the
\MyDaniel\Captcha\Contracts\CaptchaGeneratorContractinterface: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', ]; } }
-
Register your custom generator in a service provider:
public function register() { $this->app->bind('captcha.generator.question', \App\Captcha\QuestionGenerator::class); }
-
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.