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

Antispam Bundle Laravel Package

omines/antispam-bundle

Omines Antispam Bundle adds configurable spam protection to Symfony forms with honeypot fields, time-based submission checks, blocked-word filtering, and IP/email validation—no CAPTCHA friction. Lightweight, framework-native, and simple to wire into existing form types.

View on GitHub
Deep Wiki
Context7

Getting Started

omines/antispam-bundle is a Symfony bundle, not a Laravel package — install it knowing that first.

composer require omines/antispam-bundle

There is no service provider, no publishable config, no facade, and no Laravel integration. To use it in a Laravel app you either (a) pull it in as a standalone library and register the services yourself, or (b) read the source and lift the two Captcha\ classes you actually need.

Look first at:

  • src/Captcha/CaptchaInterface.php — the single-method contract (verify(Request $request)).
  • src/Captcha/Honeypot.php — ~30 lines, trivially portable.
  • src/Captcha/ReCaptcha.php — the reCAPTCHA v2/v3 verifier, uses Symfony's HTTP client and ReCaptchaResponse.
  • src/SpamProtection.php — orchestrator that iterates over enabled captchas and calls verify().

First use case (portable): copy Honeypot.php into app/Support/Antispam/Honeypot.php, drop the Symfony Request type-hint for Illuminate\Http\Request, and wrap it in a custom validation rule. You now have honeypot protection in a Laravel form without dragging in symfony/form or symfony/http-kernel.

Implementation Patterns

Pattern 1 — port the honeypot as a Laravel rule. The honeypot logic is dependency-free. Extract the "check a named field is empty" behavior into an invokable rule (new HoneypotRule()) and apply it in a FormRequest:

class ContactRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'email' => ['required', 'email'],
            '_gotcha' => [new HoneypotRule()],
        ];
    }
}

Render the _gotcha field hidden via style="display:none" and tabindex="-1" — the bundle does not hide it for you.

Pattern 2 — vendor the reCAPTCHA verifier. ReCaptcha is a thin wrapper around POST https://www.google.com/recaptcha/api/siteverify. If you want the bundle's score-threshold checks and error handling (it distinguishes hostname mismatches, action mismatches, and score thresholds), instantiate it directly with Laravel's HTTP client substituted for Symfony's HttpClientInterface:

$captcha = new ReCaptcha(
    secret: config('services.recaptcha.secret'),
    siteKey: config('services.recaptcha.site'),
    verifyUrl: 'https://www.google.com/recaptcha/api/siteverify',
    httpClient: new SymfonyHttpClientAdapter(),
    scoreThreshold: 0.5,
);

Then wrap in a validation rule or a SpamProtection service binding.

Pattern 3 — full Symfony-style usage (if you add symfony/form). Register the CaptchaType form field on an existing Symfony form and let the FormTypeExtension fire automatically. This is the intended path but rarely worth the dependency weight in a Laravel app.

Pattern 4 — driver-based switching. The bundle's config lets you toggle honeypot and captcha per environment. Mirror this in Laravel with a config/antispam.php and a SpamProtection::class singleton keyed off config('antispam.drivers'). Cheap to set up, keeps test environments deterministic (antispam.drivers => [] for feature tests).

Gotchas and Tips

  • It is not Laravel-aware. There is no config/antispam.php publish, no @antispam Blade directive, no facade. Every integration point is Symfony's container. Plan for a translation layer or extraction.
  • symfony/form is a hard transitive requirement of the FormTypeExtension. If you only want honeypot/captcha verification, install the bundle with --no-install discipline: add it, read the source, remove it, and vendor what you need. Otherwise you inherit the full Symfony form component.
  • reCAPTCHA v3 needs a score threshold and an action check. The bundle's ReCaptcha allows configuring both, but a misconfigured threshold (e.g. 0.0) silently passes all traffic. Log the returned score in development — the bundle does not surface it in exceptions by default.
  • Honeypot field must be invisible in the rendered HTML. If you render it with type="text" and only CSS-hide it, some bots still detect it. Use display:none and a plausible name (website, company) — the bundle does not enforce either.
  • SpamProtection::validate() throws vs isValid() returns bool. In a Laravel validation rule you almost always want isValid() so the failure flows through $errors; throwing bypasses the validator's message bag.
  • Testing: the bundle has no built-in test double for reCAPTCHA. Fake the verifier by binding a stub CaptchaInterface into the container — easier than intercepting HTTP. For honeypot, simply post a non-empty _gotcha field and assert the 422.
  • Symfony 7 LTS deprecation fixes (0.1.14): if you're running Laravel 10/11 you won't hit these, but they signal the maintainers are tracking the current Symfony LTS. The 0.1.x series is still pre-1.0 — treat the API as unstable and pin the version.
  • Extending: implement CaptchaInterface and tag the service omines.antispam.captcha (Symfony) or bind it into a SpamProtection manager (Laravel). This is the cleanest way to add a custom challenge (Turnstile, hCaptcha) without forking.
  • CI/tooling note: 0.1.14 is a maintenance release (cache action bump, infection update, Symfony 7 deprecation fixes) — no new features or breaking changes, but also confirms the package is still maintained, which matters for a pre-1.0 dependency you're considering vendoring.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo