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

Recaptcha2 Bundle Laravel Package

beelab/recaptcha2-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package (Symfony-only):

    composer require beelab/recaptcha2-bundle
    

    Note: Not directly usable in Laravel without adaptation.

  2. Configure Environment Variables (.env):

    APP_RECAPTCHA_SITE_KEY=your_site_key
    APP_RECAPTCHA_SECRET=your_secret_key
    
  3. Add Bundle Configuration (config/packages/beelab_recaptcha2.yaml):

    beelab_recaptcha2:
        site_key: '%env(APP_RECAPTCHA_SITE_KEY)%'
        secret: '%env(APP_RECAPTCHA_SECRET)%'
    
  4. Disable in Tests (config/packages/test/beelab_recaptcha2.yaml):

    beelab_recaptcha2:
        enabled: false
    
  5. First Use Case: Add the RecaptchaType to a Symfony form (e.g., RegistrationType):

    use Beelab\Recaptcha2Bundle\Form\Type\RecaptchaType;
    use Beelab\Recaptcha2Bundle\Validator\Constraints\Recaptcha2;
    
    $builder->add('captcha', RecaptchaType::class, [
        'constraints' => new Recaptcha2(['groups' => ['registration']]),
    ]);
    
  6. Include Script in Layout (e.g., base.html.twig):

    <script src="//www.google.com/recaptcha/api.js?hl={{ app.request.locale }}"></script>
    

Implementation Patterns

Usage Patterns

1. Form Integration

  • Standard reCAPTCHA:
    $builder->add('captcha', RecaptchaType::class, [
        'label' => 'Verify you are human',
        'mapped' => false, // Optional: if not storing the token
    ]);
    
  • Invisible reCAPTCHA (submit button):
    $builder->add('captcha', RecaptchaSubmitType::class, [
        'label' => 'Submit',
    ]);
    

2. Validation Groups

Use Symfony’s validation groups to scope reCAPTCHA to specific actions:

new Recaptcha2(['groups' => ['registration', 'contact']])

3. Custom Error Messages

Override validation messages in config/validator/validation.yaml:

Beelab\Recaptcha2Bundle\Validator\Constraints\Recaptcha2:
    message: "Invalid CAPTCHA. Please try again."

4. Dynamic Site Key

Pass the site key dynamically in templates:

{% set siteKey = app.parameters.beelab_recaptcha2.site_key %}
<div class="g-recaptcha" data-sitekey="{{ siteKey }}"></div>

5. HTTP Client Configuration

Use Symfony’s HTTP Client for requests (requires symfony/http-client):

beelab_recaptcha2:
    request_method: http_client

Workflows

Laravel Adaptation Workflow

  1. Extract Core Logic: Use the underlying google/recaptcha library directly in Laravel:

    use Google\Recaptcha\ReCaptcha;
    use Google\Recaptcha\Response;
    
    $recaptcha = new ReCaptcha($secretKey);
    $response = $recaptcha->verify($token, $remoteIp);
    
  2. Create a Validator:

    namespace App\Validators;
    
    use Google\Recaptcha\ReCaptcha;
    use Illuminate\Contracts\Validation\Rule;
    
    class ReCaptchaValidator implements Rule {
        public function passes($attribute, $value) {
            $recaptcha = new ReCaptcha(config('services.recaptcha.secret'));
            $response = $recaptcha->verify($value, request()->ip());
            return $response->success();
        }
    
        public function message() {
            return 'The CAPTCHA verification failed.';
        }
    }
    
  3. Integrate with Form Requests:

    use App\Validators\ReCaptchaValidator;
    
    public function rules() {
        return [
            'captcha' => ['required', new ReCaptchaValidator],
        ];
    }
    

Symfony Event Listeners

Listen to validation failures for analytics/logging:

use Beelab\Recaptcha2Bundle\Event\RecaptchaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RecaptchaSubscriber implements EventSubscriberInterface {
    public static function getSubscribedEvents() {
        return [
            RecaptchaEvent::ON_RECAPTCHA_FAIL => 'onRecaptchaFail',
        ];
    }

    public function onRecaptchaFail(RecaptchaEvent $event) {
        // Log failed attempts
        \Log::warning('Failed reCAPTCHA', [
            'error' => $event->getErrorCode(),
            'ip' => $event->getRequest()->getClientIp(),
        ]);
    }
}

Integration Tips

For Symfony

  • Theme Overrides: Customize the reCAPTCHA widget in form_themes/_form_theme.html.twig:

    {% block beelab_recaptcha2_widget %}
        <div class="g-recaptcha"
             data-sitekey="{{ site_key }}"
             data-size="compact"
             data-theme="dark">
        </div>
    {% endblock %}
    
  • Multi-Environment Keys: Use environment-specific keys (e.g., APP_RECAPTCHA_SITE_KEY_STAGING):

    beelab_recaptcha2:
        site_key: '%env(APP_RECAPTCHA_SITE_KEY_%kernel.environment%)%'
    
  • Caching Responses: Cache reCAPTCHA verification responses (e.g., for high-traffic forms):

    $response = $recaptcha->verify($token, $ip);
    if ($response->success()) {
        Cache::put('recaptcha_'.$token, true, now()->addMinutes(5));
    }
    

For Laravel

  • Service Provider Setup: Register the validator in AppServiceProvider:

    Validator::extend('recaptcha', function ($attribute, $value, $parameters, $validator) {
        return (new ReCaptchaValidator)->passes($attribute, $value);
    });
    
  • Blade Template Integration:

    <div class="g-recaptcha"
         data-sitekey="{{ config('services.recaptcha.site_key') }}"
         data-callback="onSubmit">
    </div>
    @push('scripts')
        <script>
            function onSubmit(token) {
                document.getElementById('captcha_token').value = token;
            }
        </script>
    @endpush
    

Gotchas and Tips

Pitfalls

  1. Duplicate Service Configuration:

    • If using Flex recipes, ensure you do not enable the google/recaptcha recipe separately. This bundle already provides the service.
    • Fix: Remove any manually created recaptcha.client service if it conflicts.
  2. Test Environment Issues:

    • The bundle disables reCAPTCHA in tests by default (enabled: false). If tests still fail, explicitly mock the RecaptchaValidator:
      $this->get('validator')->disableConstraintsFor('captcha');
      
  3. Non-Scalar Token Errors:

    • If the submitted token is not a string (e.g., array or object), the validator throws an exception.
    • Fix: Ensure your form handles the token as a string:
      $builder->add('captcha', TextType::class, [
          'mapped' => false,
      ]);
      
  4. HTTP Request Method Failures:

    • If file_get_contents() is disabled (e.g., in shared hosting), use curl_post or http_client:
      beelab_recaptcha2:
          request_method: curl_post
      
    • Note: http_client requires symfony/http-client (composer require symfony/http-client).
  5. Locale Mismatches:

    • The hl parameter in the reCAPTCHA script must match the user’s locale. If using app.request.locale, ensure it returns a valid ISO 639-1 code (e.g., en, fr).
  6. Symfony 8+ Message Customization:

    • In Symfony 8+, message customization requires a translation domain. Add this to config/packages/validator.yaml:
      Beelab\Recaptcha2Bundle\Validator\Constraints\Recaptcha2:
          message: "recaptcha.invalid"
      
    • Then define the translation in translations/messages.en.yaml:
      recaptcha:
          invalid: "The CAPTCHA verification failed. Please try again."
      

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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui