core45 / laravel-p-captcha
Advanced CAPTCHA system for Laravel applications with beam alignment, pattern matching, and computational challenges
Requires
- php: ^8.1
- ext-openssl: *
- laravel/framework: ^9.0|^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^7.0|^8.0|^9.0
- phpunit/phpunit: ^9.0
This package is auto-updated.
Last update: 2025-06-26 21:46:19 UTC
README
A sophisticated CAPTCHA package for Laravel applications featuring adaptive difficulty, multiple challenge types including beam alignment, pattern matching, and proof-of-work challenges.
Features
- Hidden Bot Detection: Invisible CAPTCHA with honeypot fields, timing validation, and JavaScript checks
- Smart Visual Challenges: Beam alignment and sequence completion only shown when bots are detected
- Modern UI: Dark/light themes with smooth animations
- Mobile Friendly: Touch-optimized for mobile devices
- High Performance: Efficient caching and rate limiting
- Security First: Single-use challenges, CSRF protection, and comprehensive logging
- Easy Integration: Simple Blade directive and middleware
Installation
Install the package via Composer:
composer require core45/laravel-p-captcha
Publish assets (required for frontend functionality):
php artisan p-captcha:install
Note: The install command is required for the CAPTCHA widget to display and function properly. Without it, you'll have unstyled/broken frontend components, though the backend validation will still work.
This command will:
- Publish the configuration file to
config/p-captcha.php
- Publish CSS and JavaScript assets to
public/vendor/p-captcha/
(required) - Create necessary directories
- Optionally update your
.gitignore
file
Advanced: Selective publishing (optional):
# Publish only configuration php artisan p-captcha:install --config # Publish only assets (minimum required) php artisan p-captcha:install --assets # Publish only views (for customization) php artisan p-captcha:install --views # Force overwrite existing files php artisan p-captcha:install --force
Basic Usage
1. Add the CAPTCHA to your Blade views
<form method="POST" action="/contact"> @csrf <!-- Your form fields --> <input type="text" name="name" required> <input type="email" name="email" required> <!-- P-CAPTCHA Widget (no parameters needed) --> @pcaptcha <button type="submit">Submit</button> </form>
Note: The @pcaptcha
directive no longer accepts parameters. All configuration is controlled via the config file (config/p-captcha.php
).
2. Protect Your Route
Add the middleware to your route:
use Core45\LaravelPCaptcha\Middleware\ProtectWithPCaptcha; Route::post('/contact/store', [ContactController::class, 'store']) ->middleware('p-captcha') ->name('contact.store');
3. Handle Success in Controller
Optionally reset attempt counter after successful submission:
use YourVendor\LaravelPCaptcha\Middleware\ProtectWithPCaptcha; class ContactController extends Controller { public function store(Request $request) { // Your form validation and processing $validated = $request->validate([ 'email' => 'required|email', 'message' => 'required|string|max:1000', ]); // Process the form... Contact::create($validated); // Reset CAPTCHA attempt counter (optional) ProtectWithPCaptcha::resetAttemptCount(); return redirect()->back()->with('success', 'Message sent successfully!'); } }
That's it! Most users will never see a CAPTCHA challenge. The system uses hidden bot detection techniques, and only shows visual challenges when suspicious behavior is detected.
How It Works
Hidden Bot Detection (Invisible to Users):
- Honeypot Fields: Hidden form fields that bots fill but humans don't see
- Timing Validation: Detects forms submitted too quickly (likely bots)
- JavaScript Validation: Ensures browser executes JavaScript properly
- Session Validation: Checks session consistency and user agent
Visual Challenges (Only When Needed):
- Beam Alignment: Drag-and-drop challenge for suspected bots
- Sequence Completion: Mathematical pattern recognition
- Adaptive Difficulty: Gets harder with repeated failures
User Experience:
- Normal Users: Complete forms without any CAPTCHA (invisible protection)
- Suspected Bots: Must complete visual challenge to proceed
- Failed Attempts: More challenges required for suspicious behavior
Advanced Usage
Custom CAPTCHA Options
You can customize the CAPTCHA widget with options:
@pcaptcha('theme=light,id=my-captcha')
Available options:
theme
:dark
(default) orlight
id
: Custom container IDauto_load
:true
(default) orfalse
Manual CAPTCHA Control
For more control, you can manually initialize and validate:
<div id="manual-captcha" class="p-captcha-container" data-auto-load="false"> <!-- CAPTCHA content will be loaded here --> </div> <script> // Initialize manually const captcha = PCaptcha.init('manual-captcha'); // Check if verified if (PCaptcha.isVerified('manual-captcha')) { console.log('CAPTCHA completed!'); } // Listen for verification events document.addEventListener('p-captcha-verified', function(event) { console.log('CAPTCHA verified:', event.detail); }); </script>
Using the Facade
You can interact with the CAPTCHA service directly:
use Core45\LaravelPCaptcha\Facades\PCaptcha; // Generate a challenge $challenge = PCaptcha::generateChallenge(); // Validate a solution $isValid = PCaptcha::validateSolution($challengeId, $solution); // Render CAPTCHA HTML $html = PCaptcha::renderCaptcha('theme=light');
Configuration
All CAPTCHA behavior is controlled via the configuration file. Publish the config file:
php artisan vendor:publish --provider="Core45\LaravelPCaptcha\Providers\PCaptchaServiceProvider" --tag="config"
Translations
The P-CAPTCHA package supports multiple languages. Translation files are included for English, Polish, and Spanish.
Available Languages
- English (
en
) - Default - Polish (
pl
) - Polski - Spanish (
es
) - EspaƱol
Using Translations
The package automatically uses Laravel's localization system. To change the language:
- Set the application locale in your
config/app.php
:
'locale' => 'pl', // For Polish 'locale' => 'es', // For Spanish
- Or set it dynamically in your application:
App::setLocale('pl');
Customizing Translations
You can publish and customize the translation files:
# Publish translation files php artisan vendor:publish --provider="Core45\LaravelPCaptcha\Providers\PCaptchaServiceProvider" --tag="translations" # This will create: # resources/lang/vendor/p-captcha/en/p-captcha.php # resources/lang/vendor/p-captcha/pl/p-captcha.php # resources/lang/vendor/p-captcha/es/p-captcha.php
Adding New Languages
To add support for a new language:
- Create a new translation file:
packages/core45/laravel-p-captcha/resources/lang/[locale]/p-captcha.php
- Copy the English translations and translate them
- The package will automatically detect and use the new language
Translation Keys
The package uses the following translation keys:
- UI Elements:
human_verification
,loading_challenge
,validate
, etc. - Status Messages:
beam_aligned
,captcha_verified_successfully
, etc. - Error Messages:
failed_to_load_challenge
,invalid_solution_try_again
, etc. - Challenge Instructions:
align_beam_source_target
,complete_sequence_select_next
, etc. - Sequence Instructions:
add_1_to_last_number
,triple_last_number
, etc. - API Messages:
too_many_requests_wait
,failed_to_validate_captcha
, etc. - Middleware Messages:
suspicious_activity_detected
,please_complete_verification_challenge
, etc.
Key Configuration Options
// config/p-captcha.php return [ // Force visual CAPTCHA to always show (bypasses bot detection) 'force_visual_captcha' => false, // Set to true to always show visual challenges // UI/UX settings 'ui' => [ 'theme' => 'light', // 'dark' or 'light' 'show_instructions' => true, 'auto_show_after_attempts' => 3, ], // Available challenge types 'challenge_types' => [ 'beam_alignment', // Drag beam source to target 'sequence_complete', // Complete number sequences ], // ... other options ];
Important Settings
force_visual_captcha
:false
(default): CAPTCHA only shows when bot detection triggers it or after failed attemptstrue
: CAPTCHA always shows, bypassing bot detection
ui.theme
: Choose between'light'
and'dark'
themes.
Bot Detection Methods
The package uses multiple invisible techniques to detect bots before showing visual challenges:
1. Honeypot Fields
Hidden form fields that are invisible to users but filled by bots:
<!-- These fields are positioned off-screen --> <input type="text" name="website" style="position:absolute;left:-10000px;"> <input type="email" name="search_username" style="position:absolute;left:-10000px;">
2. Timing Validation
Detects forms submitted suspiciously fast:
- Too Fast: Forms submitted in less than 2 seconds (likely bot)
- Too Slow: Forms submitted after 20 minutes (expired token)
- Normal: 2 seconds to 20 minutes (human behavior)
3. JavaScript Validation
Ensures browser properly executes JavaScript:
- Generates encrypted tokens via AJAX
- Validates session consistency
- Checks user agent matching
4. Session Validation
Verifies session integrity:
- Session ID consistency
- IP address validation
- User agent matching
- CSRF token validation
When Visual CAPTCHAs Appear
Visual challenges only appear when:
- Bot behavior detected (honeypot filled, timing suspicious, etc.)
- Multiple failed attempts (after 3 failures for legitimate users)
- JavaScript disabled (suspicious behavior)
- Invalid tokens (tampered requests)
Normal users experience:
- No visible CAPTCHA challenges
- Seamless form submission
- Invisible protection
Force Visual CAPTCHA (Optional)
You can force the visual CAPTCHA to always appear by setting this in your config:
// In config/p-captcha.php 'force_visual_captcha' => true,
When to use this:
- Testing: Always see the CAPTCHA during development
- High Security: Always require visual verification regardless of bot detection
- Demo Purposes: Show the CAPTCHA functionality to clients
- Compliance: Meet specific security requirements that mandate visible verification
With this setting enabled:
- All users will see visual challenges immediately
- Hidden bot detection still runs in the background
- Useful for extra security or testing scenarios
Environment-specific configuration:
// Always show in development for testing 'force_visual_captcha' => env('APP_ENV') === 'local', // Or use a specific environment variable 'force_visual_captcha' => env('PCAPTCHA_FORCE_VISUAL', false),
Then in your .env
file:
# For testing/development PCAPTCHA_FORCE_VISUAL=true # For production (default) PCAPTCHA_FORCE_VISUAL=false
Visual Challenge Types
When bot behavior is detected, users may encounter these challenges:
1. Beam Alignment
An innovative challenge where users drag a beam source to align with a target.
- Difficulty: Visual coordination
- Mobile: Touch-optimized
- Accessibility: Keyboard navigation support
2. Sequence Completion
Mathematical sequence completion challenges.
- Types: Arithmetic, geometric sequences
- Difficulty: Number complexity varies
- Educational: Engaging for users
Security Features
- Single-Use Challenges: Each challenge can only be used once
- Rate Limiting: Prevents brute force attacks
- CSRF Protection: Integrated with Laravel's CSRF system
- Session Tracking: Adaptive difficulty per user session
- Comprehensive Logging: All attempts logged for monitoring
- IP-based Protection: Optional IP blocking for suspicious activity
Customization
Custom Themes
Create custom themes by overriding CSS variables:
.p-captcha-container[data-theme="custom"] { --primary-color: #your-color; --background: your-gradient; --text-color: #your-text; }
Custom Challenge Types
Extend the service to add your own challenge types:
class CustomPCaptchaService extends PCaptchaService { protected function generateCustomChallenge(): array { // Your custom challenge logic return [ 'challenge_data' => [...], 'solution' => [...], 'instructions' => 'Your instructions' ]; } }
API Endpoints
The package provides several API endpoints:
POST /p-captcha/generate
- Generate new challengePOST /p-captcha/validate
- Validate solutionPOST /p-captcha/refresh
- Get new challengeGET /p-captcha/widget
- Get widget HTML
Events
Listen for CAPTCHA events in JavaScript:
// CAPTCHA verified successfully document.addEventListener('p-captcha-verified', function(event) { console.log('Verified:', event.detail.containerId); }); // CAPTCHA failed document.addEventListener('p-captcha-failed', function(event) { console.log('Failed:', event.detail.containerId); });
Testing
Run the package tests:
vendor/bin/phpunit
Test specific challenge types:
use Core45\LaravelPCaptcha\Services\PCaptchaService; public function test_beam_alignment_challenge() { $service = new PCaptchaService(); $challenge = $service->generateChallenge(); $this->assertArrayHasKey('challenge_data', $challenge); $this->assertArrayHasKey('solution', $challenge); }
Performance
Caching
The package uses Laravel's cache system:
- Challenge Storage: 10 minutes (configurable)
- Failure Tracking: 1 hour (configurable)
- Rate Limiting: 1 minute windows
Optimization Tips
- Use Redis: For better performance in production
- CDN Assets: Serve CSS/JS from CDN
- Cache Warming: Pre-generate challenges during low traffic
- Monitor Logs: Track performance metrics
Troubleshooting
Common Issues
CAPTCHA not showing:
- Ensure assets are published:
php artisan vendor:publish --tag=p-captcha-assets
- Check JavaScript console for errors
- Verify CSRF token is present
Validation always fails:
- Check session configuration
- Verify cache is working
- Review server logs
Styling issues:
- Publish and customize views:
php artisan vendor:publish --tag=p-captcha-views
- Override CSS variables for themes
- Check for CSS conflicts
Debug Mode
Enable debug logging in config:
'security' => [ 'log_attempts' => true, ],
Requirements
- PHP 8.1+
- Laravel 9.0+
- OpenSSL extension
License
The MIT License (MIT). Please see License File for more information.
Contributing
Please see CONTRIBUTING.md for details.
Security Vulnerabilities
If you discover a security vulnerability, please send an e-mail to security@yourpackage.com.
Credits
- Advanced CAPTCHA system implementation
- Built for Laravel by Core45
Changelog
Please see CHANGELOG.md for more information on what has changed recently.