A lightweight, high-performance CAPTCHA generation package for Laravel. It produces wave-distorted, GD-based CAPTCHA image streams with fast bitwise transformations, zero runtime asset dependencies, and simple integration with Laravel's Validator.
- Fast & Lightweight: Employs bitwise color blending and fast bilinear pixel transformations for rapid rendering.
- Zero-Config Default: Works out-of-the-box using the bundled TrueType font inside
resources/fonts/. - Integrated Route & Controller: Serves dynamic binary PNG images via a dedicated endpoint.
- Custom Validation Rule: Integrates natively into Laravel form validation via
'captcha'. - Session Timeout Protection: Prevents replay attacks with automatic expiration tracking.
- Fully Customizable: Easily configure dimensions, colors, character lengths, font choices, and wave distortion noise.
- PHP:
^8.2|^8.3|^8.4|^8.5 - Laravel Framework:
^11.0|^12.0|^13.0 - PHP Extensions:
ext-gd
You can install the package via Composer:
composer require imicodewarlock/captchaThe package service provider and route endpoints will automatically register via Laravel's Package Discovery.
Publish the configuration file and optional font assets to your host application using Artisan:
# Publish configuration
php artisan vendor:publish --tag="captcha-config"
# Publish font assets (Optional)
php artisan vendor:publish --tag="captcha-fonts"This will create config/captcha.php in your application root:
return [
// Custom absolute font path (defaults to bundled font when null)
'font' => null,
// Canvas & Word Dimensions
'width' => 239,
'height' => 70,
'wordlen' => 5,
'use_numbers' => true,
'font_size' => 25,
// Noise & Wave Distortion Parameters
'line_noise_level' => 5,
'line_thickness' => 5,
'dot_noise_level' => 100,
'dot_size' => 2,
'frequence' => [700000, 1000000, 40000000],
// Expiration Parameters (seconds)
'timeout' => 360,
'name' => 'captcha',
// RGBA Color Palettes [R, G, B, Alpha]
'line_color' => [200, 200, 200, 80],
'dot_color' => [200, 200, 200, 80],
'background_color' => [11, 11, 11, 1],
'font_color' => [255, 255, 255, 1],
];The package automatically registers the /captcha/image route named captcha.image. Use this route inside your Blade templates:
<form method="POST" action="/submit-form">
@csrf
<!-- CAPTCHA Image Stream -->
<div class="captcha-container">
<img src="{{ route('captcha.image') }}" id="captcha-img" alt="CAPTCHA">
<button type="button" onclick="document.getElementById('captcha-img').src='{{ route('captcha.image') }}?' + Math.random()">
Refresh
</button>
</div>
<!-- User Input Field -->
<input type="text" name="captcha" placeholder="Enter CAPTCHA code" required>
@error('captcha')
<span class="error">{{ $message }}</span>
@enderror
<button type="submit">Submit</button>
</form>Validate the user input in your Controller or Form Request using the 'captcha' rule:
Controller Example:
use Illuminate\Http\Request;
public function store(Request $request)
{
$request->validate([
'captcha' => 'required|captcha',
]);
// Validation passed!
return back()->with('success', 'CAPTCHA validated successfully!');
}Form Request Example:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SubmitFormRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'captcha' => ['required', 'captcha'],
];
}
}Run the package test suite locally using PHPUnit:
composer test
# or directly via PHPUnit
vendor/bin/phpunit