edulazaro / laracaptcha
Driver-based captcha for Laravel: Cloudflare Turnstile and Google reCAPTCHA v2/v3 behind a single API
Requires
- php: ^8.2
- laravel/framework: >=11.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.5|^11.0|^12.0
README
Laracaptcha
Driver-based captcha for Laravel. One API for Cloudflare Turnstile and Google reCAPTCHA v2/v3: switch providers by changing one env variable, 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
Usage
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
Use the validation rule on the token field. The field name depends on the provider (cf-turnstile-response for Turnstile, g-recaptcha-response for reCAPTCHA); get it dynamically with Captcha::responseField():
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 via prevent_reuse / 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
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.
Sponsors
Laracaptcha is supported by the following sponsors. Thank you for keeping it growing:
Author
Created by Edu Lazaro
License
Laracaptcha is open-sourced software licensed under the MIT license.
