Weave 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

Recaptcha Bundle Laravel Package

victor-prdh/recaptcha-bundle

A Symfony bundle for integrating Google reCAPTCHA into forms and controllers, with configurable keys, server-side verification, and simple validators to help protect your application from spam and automated abuse.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — there is no service provider, no facade, and no config/recaptcha.php. Treat it as a thin wrapper around google/recaptcha that you wire into Laravel yourself.

  1. composer require victor-prdh/recaptcha-bundle — the 2.2.0 release only widens the google/recaptcha constraint to allow ^2.0, so check what Composer actually resolves:
    composer show victor-prdh/recaptcha-bundle
    composer show google/recaptcha
    
  2. Look first at src/DependencyInjection/Configuration.php (the config tree), src/Resources/config/services.* (service ids/wiring), and the constraint/validator class that does the actual ReCaptcha::verify() call.
  3. If you only need verification, consider skipping the bundle entirely and depending on google/recaptcha directly — you get the same behaviour with one less abstraction and full control over the HTTP client. Reach for the bundle when you want its validator/constraint semantics and don't mind translating Symfony config into a Laravel binding.

First use case: server-side verification of a login, registration, or contact-form token in a FormRequest, returning a 422 on failure.

Implementation Patterns

Bind the client in a service provider. Translate the bundle's config array into the ReCaptcha constructor rather than trying to load Symfony YAML:

$this->app->singleton(ReCaptcha::class, fn () => (new ReCaptcha(
    secret: config('services.recaptcha.secret_key'),
    options: ['server_hostname' => config('services.recaptcha.hostname')],
))->setExpectedHostname(config('services.recaptcha.hostname')));

Validate in a FormRequest so controllers stay clean:

public function rules(): array
{
    return [
        'g-recaptcha-response' => ['required', 'string', new ReCaptchaRule()],
    ];
}

Custom rule wrapping the verifier. Keep the rule dumb — it takes the token, calls verify, and maps the Response to a ValidationException message. Put score/action assertions in the rule, not in the controller, so every form gets the same policy.

v3: check score and action. getScore() is only meaningful for v3; for v2 checkbox it can be null. Guard the comparison and fail closed when the action doesn't match what the page declared. Store the threshold in config, not in code.

Testing. Never hit Google in tests. Bind a fake in TestCase::setUp() or use Http::fake() if you swapped the transport, and assert both the happy path and the "score below threshold" path. Tokens are single-use, so a fixture token will only ever pass once against the real API — another reason to fake.

Integration tip: if you're adopting the bundle purely for constraint parity with an existing Symfony app, wrap the validator's validate() in a Laravel rule object and leave the rest of the bundle unused. The dependency footprint stays small and the upgrade path (this release) is trivial.

Gotchas and Tips

  • 2.2.0 is a constraint widening, not a behaviour change. No BC breaks for anyone already installing it. It matters only if you were previously blocked: on google/recaptcha ^1.x nothing changes; if you were pinned to 2.x elsewhere, the bundle is now installable alongside it. Re-run composer update --with-dependencies and diff the lockfile before assuming an upgrade did anything.
  • google/recaptcha 2.x raises the PHP floor (7.4+, and check the exact patch constraint against your CI matrix). If you support 7.2/7.3 you cannot take this release. Pin google/recaptcha explicitly rather than letting two constraints negotiate.
  • API drift between 1.x and 2.x of google/recaptcha: response accessors and option keys have shifted across majors. If you write code against the underlying library directly, verify getScore(), getAction(), and getHostname() signatures against the version Composer actually picked — don't trust docs for the other major.
  • Symfony config tree ≠ Laravel config. Don't try to publish or load the bundle's YAML; the Configuration class is a Symfony TreeBuilder and will reject unknown keys. Mirror the values into config/services.php instead.
  • setExpectedHostname() is a meaningful hardening step and is easy to forget — verification passes without it, so the omission is silent.
  • Fail-open vs fail-closed on transport errors. Google returning 5xx or a timeout means you have no verdict. Decide explicitly (usually: reject on protected actions, allow on low-risk ones) and log it; don't let an exception bubble into a 500.
  • Clock skew / timeouts: tokens expire after ~2 minutes and verification has a default network timeout. Set both deliberately; a slow Google response should not stall your request cycle.
  • Config cache in production: if you read config('services.recaptcha.*') inside a closure, run php artisan config:cache after changing the secret, otherwise you'll debug a stale key for an hour.
  • Extension points: the custom validation rule and the injected ReCaptcha binding are your two seams — everything else is bundle internals you shouldn't depend on. Keep the secret in .env and out of the repository; rotate it via env vars, never by editing config files on the server.
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast