Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Captcha Laravel Package

gregwar/captcha

Generate CAPTCHA images in PHP with Gregwar CaptchaBuilder. Create, save, output, or embed captchas inline, retrieve and validate the phrase against user input, tweak distortion/background, and optionally build captchas resistant to OCR (with ocrad).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require gregwar/captcha
    

    Ensure your project meets the PHP 8.2+ requirement (Laravel 10+ compatible).

  2. Basic Usage:

    use Gregwar\Captcha\CaptchaBuilder;
    
    $builder = new CaptchaBuilder();
    $builder->build();
    
    // Store the phrase in session for later validation
    session(['captcha_phrase' => $builder->getPhrase()]);
    
    // Output the CAPTCHA image
    header('Content-Type: image/jpeg');
    $builder->output();
    
  3. Validation:

    $userInput = request('captcha');
    $isValid = $builder->testPhrase($userInput);
    // OR compare with session:
    $isValid = $builder->testPhrase(session('captcha_phrase'));
    
  4. Inline HTML Usage (for forms):

    <img src="<?php echo $builder->inline(); ?>" />
    

First Use Case

Protect a Login Form:

// In your controller:
$builder = new CaptchaBuilder();
session(['captcha_phrase' => $builder->getPhrase()]);

// In your blade view:
<img src="{{ $builder->inline() }}" alt="CAPTCHA" />

// Validation logic:
$request->validate([
    'captcha' => ['required', function ($attribute, $value, $fail) {
        $builder = new CaptchaBuilder();
        if (!$builder->testPhrase($value)) {
            $fail('The CAPTCHA code is incorrect.');
        }
    }],
]);

Implementation Patterns

Core Workflows

1. CAPTCHA Generation & Storage

  • Pattern: Generate CAPTCHA once per session/request and store the phrase securely.
    // In a middleware or service:
    public function generateCaptcha()
    {
        $builder = new CaptchaBuilder();
        $builder->build();
        session(['captcha_phrase' => $builder->getPhrase()]);
        return $builder;
    }
    
  • Laravel Integration: Use a service provider to bind the builder for dependency injection.
    // In AppServiceProvider
    $this->app->singleton(CaptchaBuilder::class, function () {
        return new CaptchaBuilder();
    });
    

2. Validation Logic

  • Pattern: Reuse the same builder instance for validation (or regenerate if needed).
    // In a FormRequest or controller:
    $builder = app(CaptchaBuilder::class);
    if (!$builder->testPhrase($request->captcha)) {
        return back()->withErrors(['captcha' => 'Invalid CAPTCHA.']);
    }
    

3. Dynamic CAPTCHA Customization

  • Pattern: Customize CAPTCHA appearance per use case (e.g., stricter for admin forms).
    $builder = new CaptchaBuilder();
    $builder
        ->setMaxBehindLines(3)
        ->setMaxFrontLines(2)
        ->setScatterEffect(true)
        ->buildAgainstOCR(); // For high-security forms
    

4. OCR-Resistant CAPTCHAs

  • Pattern: Use buildAgainstOCR() for forms where bots are likely (e.g., contact forms).
    $builder->buildAgainstOCR(200, 50); // Wider and taller for OCR resistance
    

5. Testing CAPTCHAs

  • Pattern: Mock the builder in tests to avoid flakiness.
    // In a test:
    $builder = $this->createMock(CaptchaBuilder::class);
    $builder->method('testPhrase')->willReturn(true);
    $this->app->instance(CaptchaBuilder::class, $builder);
    

Integration Tips

Laravel-Specific

  • Form Requests: Centralize validation logic in a FormRequest class.

    public function rules()
    {
        return [
            'captcha' => ['required', 'string', new CaptchaRule],
        ];
    }
    
    class CaptchaRule implements Rule
    {
        public function passes($attribute, $value)
        {
            return app(CaptchaBuilder::class)->testPhrase($value);
        }
    }
    
  • Caching: Cache the CAPTCHA image for 5 minutes to reduce generation overhead.

    $key = 'captcha_' . uniqid();
    Cache::put($key, $builder->get(), now()->addMinutes(5));
    return $key; // Return as image URL
    
  • Filament Admin: Use the Filament extension for admin panel protection.

    use MarcoGermani87\FilamentCaptcha\FilamentCaptcha;
    
    FilamentCaptcha::make()
        ->maxAttempts(3)
        ->build();
    

Performance

  • Pre-Generate CAPTCHAs: Generate CAPTCHAs during idle periods (e.g., via Laravel queues) and serve cached images.
  • Limit Effects: Disable unnecessary effects (e.g., setIgnoreAllEffects(true)) for low-security forms to improve rendering speed.

Security

  • Rate Limiting: Combine CAPTCHAs with Laravel’s throttle middleware to prevent brute-force attacks.
    Route::middleware(['throttle:5,1'])->group(function () {
        // CAPTCHA-protected routes
    });
    

Gotchas and Tips

Pitfalls

  1. Session Management:

    • Issue: Forgetting to clear the CAPTCHA phrase from the session after validation can lead to stale phrases.
    • Fix: Clear the session after validation:
      session()->forget('captcha_phrase');
      
  2. OCR Detection Overhead:

    • Issue: buildAgainstOCR() can be slow if ocrad is not optimized or if the system lacks shell_exec support.
    • Fix: Use a fallback for OCR-resistant CAPTCHAs:
      try {
          $builder->buildAgainstOCR();
      } catch (\Exception $e) {
          $builder->build(200, 50)->setScatterEffect(true);
      }
      
  3. Font Paths:

    • Issue: Custom fonts may not load if paths are incorrect, causing CAPTCHAs to render with default fonts.
    • Fix: Verify font paths in vendor/gregwar/captcha/src/Gregwar/Captcha/fonts/.
  4. Image Output Type:

    • Issue: Changing setImageType() to png or gif may break existing clients expecting JPEG.
    • Fix: Default to jpeg unless explicitly needed:
      $builder->setImageType('jpeg');
      
  5. PHP Version Mismatch:

    • Issue: Using PHP < 8.2 may trigger deprecation warnings or errors due to strict typing.
    • Fix: Upgrade PHP or use a lower version of the package (e.g., v1.3.0).

Debugging

  1. CAPTCHA Not Displaying:

    • Check: Ensure header('Content-Type: image/jpeg') is set before output().
    • Debug: Save the CAPTCHA to a file to inspect:
      $builder->save(storage_path('app/captcha.jpg'));
      
  2. Validation Failing:

    • Check: Case sensitivity (e.g., A vs a). CAPTCHAs are case-sensitive by default.
    • Debug: Log the stored and input phrases:
      \Log::debug('Stored:', ['phrase' => session('captcha_phrase')]);
      \Log::debug('Input:', ['phrase' => $request->captcha]);
      
  3. Performance Bottlenecks:

    • Check: Use setIgnoreAllEffects(true) to disable all effects and measure rendering time.
    • Debug: Profile with Laravel Debugbar to identify slow methods (e.g., buildAgainstOCR).

Tips

  1. Custom Phrases:

    • Use PhraseBuilder for controlled character sets (e.g., numeric-only CAPTCHAs):
      $phraseBuilder = new PhraseBuilder(6, '0123456789');
      $builder = new CaptchaBuilder(null, $phraseBuilder);
      
  2. Background Customization:

    • Use setBackgroundImages() for themed CAPTCHAs (e.g., match your brand):
      $builder->setBackgroundImages([
          public_path('images/bg1.png'),
          public_path('images/bg2.png'),
      ]);
      
  3. Laravel View Composers:

    • Inject CAPTCHAs into views globally:
      // In AppServiceProvider
      View::composer('*', function ($view) {
          $view->with('captcha', app(CaptchaBuilder::
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky