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