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

Captcha Form Bundle Laravel Package

gremo/captcha-form-bundle

gremo/captcha-form-bundle adds configurable CAPTCHA protection to Symfony forms via a reusable form type, helping block bots and spam. It handles challenge generation and validation with minimal setup and integrates cleanly into existing form workflows, making it suitable for public-facing forms suc...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. Before doing anything, decide which of two paths you are on:

  1. You are actually working in Symfony (or a Symfony app inside a larger stack) — install and use it normally.
  2. You are in a Laravel app — do not expect composer require gremo/captcha-form-bundle to "just work." Laravel has no bundle registration, no Symfony Form component, and no auto-wired services.yaml config. You will either run it inside a Symfony kernel or, more realistically, mine the adapter pattern and port it (see below).

First steps (Symfony path)

composer require gremo/captcha-form-bundle

Then, in order:

  1. Read composer.json first. Check the symfony/* and php constraints against your project. Given the age/size of this package, expect constraints that predate Symfony 5/6.
  2. Open DependencyInjection/ and Resources/config/ to see the service IDs and the configuration tree. The config root is conventionally gremo_captcha; verify the adapter node names there rather than guessing.
  3. Open Form/Type/ to find the CAPTCHA form type and Adapter/ to find the adapter interface implemented by each provider.
  4. Register the bundle (config/bundles.php on modern Symfony, AppKernel on legacy), configure an adapter, then add the form type to one form.

First use case

Add a CAPTCHA to a single public form (registration, contact, password reset request) and validate it server-side through the bundle's form type. Start with exactly one form and one adapter. Do not wire it into every form on day one — the bundle's value is the swappable adapter, and you want to confirm the adapter lifecycle (render token, persist state in session, validate on submit) before scaling.

Implementation Patterns

Symfony usage

Register the bundle, pick an adapter in config, and attach the form type:

# config/packages/gremo_captcha.yaml
gremo_captcha:
    adapter: gremio_captcha.adapter.<name>   # confirm exact service id in Resources/config
$builder->add('captcha', CaptchaType::class); // confirm FQCN in Form/Type/

The important architectural detail is that the form type delegates to an adapter. That means the day-to-day pattern is: keep business forms adapter-agnostic, and swap the adapter per environment.

Environment-based adapter swapping

A very practical pattern with this bundle:

  • Production: a real provider adapter.
  • test / dev: a no-op or fixed-value adapter, so feature tests and local logins don't require external CAPTCHA calls.

Override the adapter service or config in config/packages/test/. This is the single biggest quality-of-life win with adapter-based CAPTCHA bundles; without it your CI will either hit third-party APIs or fail on token validation.

Laravel port pattern

If you are a Laravel developer and want the same shape without the Symfony coupling, mirror the bundle's design rather than its code:

// config/captcha.php
return ['driver' => env('CAPTCHA_DRIVER', 'gregwar')];
interface CaptchaAdapter
{
    public function render(): string;          // markup or image URL
    public function validate(?string $value, Request $request): bool;
}

Bind the adapter in a service provider, resolve it in a Blade component/partial, and wrap validation in a custom validation rule or a FormRequest:

class CaptchaRule implements ValidationRule
{
    public function __construct(private CaptchaAdapter $adapter) {}

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! $this->adapter->validate($value, request())) {
            $fail('The CAPTCHA is incorrect.');
        }
    }
}

Then 'captcha' => ['required', new CaptchaRule(app(CaptchaAdapter::class))] in the FormRequest. This gives you the bundle's main benefit — swappable providers — with Laravel-native validation, localization, and testing.

Integration tips

  • Keep the adapter behind an interface, and never let controllers reference a concrete provider.
  • Render the CAPTCHA in one Blade partial (or Twig block) so a driver swap touches one file.
  • Add an explicit "refresh" endpoint if the provider's token expires; CAPTCHA sessions go stale on long forms.
  • For stateless/token APIs (Sanctum, mobile clients), don't put CAPTCHA in the API middleware. Use it only on browser-facing auth endpoints; otherwise you break clients that can't hold a session.
  • Pair CAPTCHA with a honeypot field and rate limiting. CAPTCHA alone is a poor first line of defense and hurts accessibility.

Gotchas and Tips

  • Symfony-only, low-maturity package. One star and zero dependents is a strong signal: treat it as reference implementation, not a dependency you build a critical auth flow on. Read the last commit date, open issues, and Symfony version constraints before committing; expect to vendor or fork it.
  • No Laravel auto-discovery. There is no Illuminate\Support\ServiceProvider, no config/ publish tag, no facade. Any "install guide" you find assumes Symfony's kernel and container.
  • Form component mismatch. Symfony Form types are not Blade/HTML helpers. You cannot @include a Symfony form type. Any port means rewriting the rendering layer, not just the validation layer.
  • Container compile failures from adapter config. Adapter names usually map to service IDs; a typo yields a container compile error, not a friendly runtime message. On Symfony, run bin/console debug:config gremo_captcha and debug:container --tag=...; clear cache after config edits. On a ported Laravel version, run php artisan config:clear.
  • Session coupling. Most CAPTCHA adapters store the expected answer/token in session. Verify this explicitly before using in a horizontally scaled app: multiple app servers require a shared session store (Redis/DB), or validation will intermittently fail. This is the #1 "works locally, fails in prod" bug with CAPTCHA.
  • CSRF interactions. CAPTCHA form types are often added to forms that also use CSRF tokens. When porting, don't collapse both into one hidden field or one validation message — users cannot tell which failed.
  • Cache and asset paths. Image-based CAPTCHAs expose a route and often write to a cache directory. Check permissions and CDN/proxy behavior; a cached CAPTCHA image is a security bug.
  • CSP and accessibility. If you render an image, ensure the route is allowed by your Content-Security-Policy and provide an audio/text alternative. If you render a third-party widget, load it with explicit nonce/integrity handling.
  • Debugging validation failures. Log the adapter name, token presence (not the token itself), and session ID correlation. Silent false returns from validate() are the usual symptom of an expired token, wrong adapter, or missing session.
  • Extension points worth knowing. The adapter interface is the intended extension point — implement it to add a provider or a test double. If the bundle exposes a form type extension hook, prefer decorating the form type over editing vendor code; if it doesn't, fork and keep your patch in a local package.
  • Alternatives before you commit. For Laravel, mews/captcha, a reCAPTCHA/hCaptcha SDK, or a thin custom adapter around Gregwar's captcha are all lower-risk than porting an unmaintained Symfony bundle. For Symfony projects, check whether gregwar/captcha-bundle or a maintained successor already covers your needs.
  • Opportunity read. With 1 star, 0 dependents, and an opportunity score of 13.5, this is not a package to standardize on. Use it to learn the adapter + form-type pattern, then implement that pattern natively in your framework of choice.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager