thecoderraman / laravel-captcha
Captcha verification for Laravel
Requires
- php: ^8.3
- illuminate/contracts: ^10.0||^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9||^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^10.0.0||^9.0.0||^8.22.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2025-06-03 15:58:27 UTC
README
Laravel CAPTCHA Package
A flexible and extensible Laravel package for integrating multiple CAPTCHA services including Google reCAPTCHA, hCaptcha, and custom implementations.
Table of Contents
- Features
- Major Technologies
- Structure
- Requirements
- Installation
- Configuration
- Environment Variables
- Usage
- Available Drivers
- Creating Custom Drivers
- Validation
- Testing
- API Reference
- Configuration Options
- Troubleshooting
- Contributing
- Repository Branches
- Contributions
- Pull Requests
- License
- Authors
- Code of Conduct
- Security Vulnerabilities
- Support
Features
- 🔒 Multiple CAPTCHA providers (Google reCAPTCHA v2, hCaptcha)
- 🎯 Easy configuration and setup
- 🔧 Extensible architecture for custom CAPTCHA drivers
- 🧪 Testing-friendly with NullCaptcha driver
- 📦 Laravel package auto-discovery support
- 🎨 Facade support for clean syntax
- ⚡ Configurable global enable/disable functionality
Major Technologies
- laravel
Structure
├───config ├───src └───tests ├───Feature └───Unit
Requirements
- PHP >= 8.3
Installation
Install the package via Composer:
composer require thecoderraman/laravel-captcha
Publish the configuration file:
php artisan vendor:publish --provider="TheCoderRaman\Captcha\CaptchaServiceProvider" --tag="config"
Configuration
The package configuration is located at config/captcha.php
. Here's the basic structure:
<?php use TheCoderRaman\Captcha\Enums\Captcha; use TheCoderRaman\Captcha\Drivers\Hcaptcha; use TheCoderRaman\Captcha\Drivers\ReCaptcha; use TheCoderRaman\Captcha\Drivers\NullCaptcha; return [ /* |-------------------------------------------------------------------------- | Captcha Verification Status |-------------------------------------------------------------------------- | | Enable/disable captcha verification globally. When set to false, | CAPTCHA will be replaced by the NullCaptcha handler. | */ 'status' => true, /* |-------------------------------------------------------------------------- | Default Captcha Handler |-------------------------------------------------------------------------- | | Specify which captcha driver to use as default. | */ 'default' => Captcha::NullCaptcha->value, /* |-------------------------------------------------------------------------- | CAPTCHA Driver Class Mappings |-------------------------------------------------------------------------- | | Maps enum values to their respective driver class implementations. | */ 'drivers' => [ Captcha::Hcaptcha->value => Hcaptcha::class, Captcha::ReCaptcha->value => ReCaptcha::class, Captcha::NullCaptcha->value => NullCaptcha::class, ], /* |-------------------------------------------------------------------------- | Captcha Configurations |-------------------------------------------------------------------------- | | Specific configurations for each CAPTCHA service. | */ 'captchas' => [ 'null' => [ 'key' => null, 'secret' => null, 'url' => null, ], 'hcaptcha' => [ 'key' => env('HCAPTCHA_SITE_KEY'), 'secret' => env('HCAPTCHA_SECRET_KEY'), 'url' => 'https://hcaptcha.com/siteverify', ], 'recaptcha' => [ 'key' => env('RECAPTCHA_SITE_KEY'), 'secret' => env('RECAPTCHA_SECRET_KEY'), 'url' => 'https://www.google.com/recaptcha/api/siteverify', ], ], ];
Environment Variables
Add the following environment variables to your .env
file:
# hCaptcha Configuration HCAPTCHA_SITE_KEY=your_hcaptcha_site_key HCAPTCHA_SECRET_KEY=your_hcaptcha_secret_key # Google reCAPTCHA Configuration RECAPTCHA_SITE_KEY=your_recaptcha_site_key RECAPTCHA_SECRET_KEY=your_recaptcha_secret_key
Usage
Basic Usage with Facade
<?php use TheCoderRaman\Captcha\Facades\Captcha; // Get the default CAPTCHA driver $captcha = Captcha::driver(); // Get a specific CAPTCHA driver $hcaptcha = Captcha::driver('hcaptcha'); $recaptcha = Captcha::driver('recaptcha'); // Render CAPTCHA HTML echo $captcha->getCaptcha(); // Render CAPTCHA scripts echo $captcha->getScript(); // Render CAPTCHA styles echo $captcha->getStyle(); // Verify CAPTCHA response $isValid = $captcha->verify();
Using Dependency Injection
<?php use TheCoderRaman\Captcha\Captcha; class ContactController extends Controller { protected $captcha; public function __construct(Captcha $captcha) { $this->captcha = $captcha; } public function showForm() { $captchaHtml = $this->captcha->getCaptcha(); $captchaScript = $this->captcha->getScript(); return view('contact.form', compact('captchaHtml', 'captchaScript')); } public function submitForm(Request $request) { if (!$this->captcha->verify()) { return back()->withErrors(['captcha' => 'CAPTCHA verification failed.']); } // Process form submission } }
Blade Templates
Create a Blade template for displaying CAPTCHA:
{{-- resources/views/contact/form.blade.php --}} @extends('layouts.app') @push('styles') {!! Captcha::getStyle() !!} @endpush @push('scripts') {!! Captcha::getScript() !!} @endpush @section('content') <form method="POST" action="{{ route('contact.submit') }}"> @csrf <div class="form-group"> <label for="name">{{ trans('Name') }}</label> <input type="text" name="name" id="name" class="form-control" required> </div> <div class="form-group"> <label for="email">{{ trans('Email') }}</label> <input type="email" name="email" id="email" class="form-control" required> </div> <div class="form-group"> <label for="message">{{ trans('Message') }}</label> <textarea name="message" id="message" class="form-control" required></textarea> </div> {{-- CAPTCHA Section --}} <div class="form-group"> {!! Captcha::getCaptcha() !!} @error('captcha') <div class="text-danger">{{ $message }}</div> @enderror </div> <button type="submit" class="btn btn-primary">Submit</button> </form> @endsection
Available Drivers
1. Google reCAPTCHA v2
// Configure in config/captcha.php 'default' => Captcha::ReCaptcha->value, // Use in controller $recaptcha = Captcha::driver('recaptcha'); $isValid = $recaptcha->verify();
2. hCaptcha
// Configure in config/captcha.php 'default' => Captcha::Hcaptcha->value, // Use in controller $hcaptcha = Captcha::driver('hcaptcha'); $isValid = $hcaptcha->verify();
3. NullCaptcha (Testing/Development)
// Configure in config/captcha.php 'default' => Captcha::NullCaptcha->value, // This driver always returns true for verification // Useful for testing and development environments
Creating Custom Drivers
You can create custom CAPTCHA drivers by extending the base Driver
class:
<?php namespace App\Captcha\Drivers; use Illuminate\Http\Request; use TheCoderRaman\Captcha\Drivers\Driver; class CustomCaptcha extends Driver { protected string $key; protected string $secret; protected string $url; public function __construct(string $key = null, string $secret = null, string $url = null) { $this->key = $key; $this->secret = $secret; $this->url = $url; } public function getCaptcha(): string { return '<div class="custom-captcha" data-sitekey="' . $this->key . '"></div>'; } public function getStyle(): string { return '<style>.custom-captcha { /* styles */ }</style>'; } public function getScript(): string { return '<script src="https://example.com/captcha.js"></script>'; } public function verify(Request $request): bool { $response = $request->input('custom-captcha-response'); if (empty($response)) { return false; } $result = $this->client->post($this->url, [ 'secret' => $this->secret, 'response' => $response, 'remoteip' => $request->ip(), ]); return $result->json('success', false); } }
Register your custom driver:
// In a service provider use TheCoderRaman\Captcha\Facades\Captcha; Captcha::extend('custom', function ($config) { return new CustomCaptcha( $config['key'], $config['secret'], $config['url'] ); });
Validation
Using Laravel Validation
Create a custom validation rule:
<?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; use TheCoderRaman\Captcha\Facades\Captcha; class CaptchaRule implements Rule { public function passes($attribute, $value) { return Captcha::verify(request()); } public function message() { return 'The CAPTCHA verification failed.'; } }
Use in your controller:
use App\Rules\CaptchaRule; public function store(Request $request) { $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email', 'message' => 'required|string', 'captcha' => ['required', new CaptchaRule], ]); // Process the validated data }
Testing
The package includes a NullCaptcha
driver for testing purposes:
<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; class ContactFormTest extends TestCase { use RefreshDatabase; public function test_contact_form_submission_with_captcha() { // Set NullCaptcha for testing config(['captcha.default' => 'null']); $response = $this->post('/contact', [ 'name' => 'John Doe', 'email' => 'john@example.com', 'message' => 'Test message', ]); $response->assertStatus(200); } }
API Reference
Captcha Manager
Methods
driver(string $driver = null)
: Get a CAPTCHA driver instanceextend(string $driver, Closure $callback)
: Register a custom drivergetDefaultDriver()
: Get the default driver name
Driver Interface
All CAPTCHA drivers implement the DriverInterface
:
Methods
getCaptcha(): string
: Render the CAPTCHA HTML widgetgetScript(): string
: Render required JavaScript codegetStyle(): string
: Render required CSS stylesverify(Request $request): bool
: Verify the CAPTCHA response
Configuration Options
Option | Type | Default | Description |
---|---|---|---|
status |
boolean | true |
Enable/disable CAPTCHA globally |
default |
string | 'null' |
Default CAPTCHA driver |
drivers |
array | [...] |
Driver class mappings |
captchas |
array | [...] |
Driver-specific configurations |
Troubleshooting
Common Issues
-
CAPTCHA not displaying
- Check if the site key is correctly configured
- Ensure the driver is properly registered
- Verify that scripts and styles are included
-
Verification always fails
- Verify the secret key is correct
- Check network connectivity to CAPTCHA service
- Ensure the request contains the CAPTCHA response
-
Package not auto-discovered
- Manually register the service provider in
config/app.php
- Clear configuration cache:
php artisan config:clear
- Manually register the service provider in
Debug Mode
Enable debug logging by setting the log level in your .env
:
LOG_LEVEL=debug
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
Repository Branches
- master -> any pull request of changes this branch
- main -> don´t modify, this is what is running in production
Contributions
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate.
Pull Requests
- Fork the repo and create your branch:
#[type]/PR description
- Ensure to describe your pull request:
Edit the PR title by adding a semantic prefix like
Added
,Updated:
,Fixed:
etc. Title:#[issue] PR title -> #90 Fixed styles the button
License
This package is open-sourced software licensed under the MIT license.
Authors
Code of Conduct
In order to ensure that the Laravel Captcha community is welcoming to all, please review and abide by the Code of Conduct.
Security Vulnerabilities
If you discover a security vulnerability within Laravel Captcha, please send an e-mail to Raman Verma via e-mail. All security vulnerabilities will be promptly addressed.
Support
For support, please open an issue on the GitHub repository.