wilycode / recaptcha-validator
Google reCAPTCHA v3 verification and a reusable WilyCode validator.
Requires
- php: ^8.4
- ext-filter: *
- ext-json: *
- wilycode/validator: ^0.1
Requires (Dev)
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-26 20:56:46 UTC
README
WilyCode PHP Ecosystem
This package is part of WilyCode, a collection of independent PHP libraries. Each package has its own repository, Composer installation and releases.
Server-side Google reCAPTCHA v3 verification with action and score checks, designed for WilyCode forms and standalone input validation.
The package verifies the provider response, expected action and minimum score on the server. It does not render a widget or execute browser JavaScript; the consuming application remains responsible for requesting a fresh v3 token when the protected action occurs.
Contents
- Installation
- Quick start
- Integration with WilyCode Form
- Configuration and security
- Requirements
- Error handling
- Development
Installation
composer require wilycode/recaptcha-validator
Quick start
use WilyCode\Recaptcha\GoogleRecaptchaVerifier; use WilyCode\Recaptcha\RecaptchaConfiguration; use WilyCode\Recaptcha\RecaptchaValidator; $configuration = new RecaptchaConfiguration( siteKey: $_ENV['GOOGLE_RECAPTCHA_SITE_KEY'] ?? '', secretKey: $_ENV['GOOGLE_RECAPTCHA_SECRET_KEY'] ?? '', minimumScore: 0.5, action: 'contact_form', ); $validator = new RecaptchaValidator( new GoogleRecaptchaVerifier($configuration), $_SERVER['REMOTE_ADDR'] ?? null, ); $responseToken = $_POST['g-recaptcha-response'] ?? ''; if (!$validator->isValid($responseToken)) { $errors = $validator->getErrors(); }
Integration with WilyCode Form
Install wilycode/form separately if you want to use this validator inside a form. It is not required for standalone verification.
use WilyCode\Form\Form; use WilyCode\Recaptcha\GoogleRecaptchaVerifier; use WilyCode\Recaptcha\RecaptchaConfiguration; use WilyCode\Recaptcha\RecaptchaValidator; final class ContactForm extends Form { protected function init(): void { $config = new RecaptchaConfiguration( siteKey: $_ENV['GOOGLE_RECAPTCHA_SITE_KEY'] ?? '', secretKey: $_ENV['GOOGLE_RECAPTCHA_SECRET_KEY'] ?? '', action: 'contact_form', ); $this->addField('message'); $this->addField('g-recaptcha-response') ->addValidator(new RecaptchaValidator(new GoogleRecaptchaVerifier($config))); } }
The application must obtain a fresh token for the configured action on each submission and send it with the form. The reCAPTCHA JavaScript snippet and form rendering belong to the application.
Configuration and security
The server verifies the token against Google's HTTPS endpoint. It checks the
success flag, the configured action, and a score in the documented 0–1 range.
The library does not enforce the response hostname or challenge_ts;
applications that need these additional checks should extend their verification
policy or implement RecaptchaVerifierInterface. Configure allowed domains
correctly in the reCAPTCHA admin console.
- Configure both
siteKeyandsecretKey; missing keys raiseInvalidArgumentExceptionso production verification cannot silently switch off. - For development only, disable verification explicitly:
$configuration = RecaptchaConfiguration::disabled();. Disabled mode approves all tokens; never enable it in production. minimumScoremust be between0.0and1.0;actionmust match the action used when generating the token in the browser.- Only the site key belongs in frontend code; keep the secret key on the server and out of logs or version control.
- Provider communication uses HTTPS without following redirects and with a five-second timeout. Failed HTTP requests and invalid provider responses are treated as service unavailability, never as successful verification.
- reCAPTCHA tokens are short-lived and single-use. Request a new token for every submission; do not cache a successful verdict for subsequent requests.
Error handling
RecaptchaValidator produces these WilyCode error codes:
| Error code | Meaning |
|---|---|
validation.recaptcha.failed |
Invalid, expired or duplicate token, wrong action, or score below the threshold. |
validation.recaptcha.unavailable |
Transport failure, malformed response or provider configuration failure. |
Both outcomes fail validation. Repeated isValid() calls start with a clean error list, so an earlier failure does not remain after a successful retry. The application decides how to display these errors; it should not automatically bypass reCAPTCHA when Google is unavailable.
Requirements
- PHP
^8.4 - PHP extensions
filterandjson wilycode/validator^0.1
Development
composer install
composer validate --strict
composer test
GitHub Actions runs PHPUnit on PHP 8.4 and 8.5. Tests use an injected transport and do not contact Google.
License
MIT. See LICENSE.