Laracaptcha

Laracaptcha is a driver-based captcha for Laravel. One API for Cloudflare Turnstile and Google reCAPTCHA v2/v3: you switch providers by changing one env variable, with no code changes.
Installation
composer require edulazaro/laracaptcha
Set your driver and keys in .env:
CAPTCHA_DRIVER=turnstile TURNSTILE_KEY=0x4AAA... TURNSTILE_SECRET=0x4AAA... # Or for reCAPTCHA (v2 / v3): # CAPTCHA_DRIVER=recaptcha_v2 # RECAPTCHA_KEY=... # RECAPTCHA_SECRET=...
Optionally publish the config:
php artisan vendor:publish --tag=laracaptcha-config
In a form
Drop the widget component inside any form. It renders the right markup and loads the provider script for the configured driver:
<form method="POST" action="/register"> @csrf ... <x-laracaptcha::widget /> <button type="submit">Register</button> </form>
For reCAPTCHA v3 the widget is invisible and tokens are generated on submit. You can tag the action:
<x-laracaptcha::widget action="register" />
Validating the token
The token field name depends on the provider (cf-turnstile-response for Turnstile, g-recaptcha-response for reCAPTCHA) so get it dynamically rather than hardcoding it:
use EduLazaro\Laracaptcha\Rules\Captcha; use EduLazaro\Laracaptcha\Facades\Captcha as CaptchaFacade; $request->validate([ CaptchaFacade::responseField() => ['required', new Captcha], ]);
The rule includes replay protection: a token that already passed once is rejected. Configurable through prevent_reuse and reuse_ttl.
Verifying manually
use EduLazaro\Laracaptcha\Facades\Captcha; $result = Captcha::verify($token, $request->ip()); $result->success; // bool $result->score; // float|null (reCAPTCHA v3) $result->errorCodes; // array
To use a specific driver regardless of the default:
Captcha::driver('recaptcha_v3')->verify($token);
Testing
use EduLazaro\Laracaptcha\Facades\Captcha; $fake = Captcha::fake(); // all verifications pass $fake = Captcha::fake(success: false); // all verifications fail $fake = Captcha::fake(score: 0.9); // pass with a score $fake->attempts(); // recorded [token, ip] pairs
No HTTP requests are made while faked.
Dev keys
Cloudflare publishes always-pass test keys for local development:
| Sitekey | 1x00000000000000000000AA |
| Secret | 1x0000000000000000000000000000000AA |
built and maintained by Edu Lazaro · MIT license