backend2-plus/google-captcha-bundle
composer require sasa1007/google-captcha-bundle
config/packages/google_captcha.yaml with your secret key:
google_captcha:
secret: '%env(GOOGLE_CAPTCHA_SECRET)%'
.env:
GOOGLE_CAPTCHA_SECRET=your_secret_key_here
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
Verify a form submission in a controller:
use BeckUp\GoogleCaptchaBundle\Service\GoogleCaptchaService;
public function submitForm(Request $request, GoogleCaptchaService $captchaService)
{
$result = $captchaService->verify($request);
if (!$result->success) {
$this->addFlash('error', 'reCAPTCHA verification failed');
return $this->redirectToRoute('form_route');
}
// Proceed with form processing
}
Form Validation Integration: Use the service in a form type validator:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('captcha_service', GoogleCaptchaService::class);
}
public function validate(FormInterface $form, ExecutionContextInterface $context)
{
$request = $this->getRequest();
$result = $this->captchaService->verify($request);
if (!$result->success) {
$context->buildViolation('reCAPTCHA verification failed')
->atPath('captcha')
->addViolation();
}
}
API Endpoint Protection: Validate reCAPTCHA for API endpoints (e.g., contact forms):
public function apiContact(Request $request, GoogleCaptchaService $captchaService)
{
$result = $captchaService->verify($request);
if (!$result->success) {
return $this->json(['error' => 'Invalid reCAPTCHA'], 403);
}
// Process API request
}
Dynamic Site Key Handling: Override the site key per environment or route:
# config/packages/google_captcha.yaml
google_captcha:
secret: '%env(GOOGLE_CAPTCHA_SECRET)%'
site_key: '%env(GOOGLE_CAPTCHA_SITE_KEY)%' # Optional override
Event-Based Validation: Trigger reCAPTCHA validation on custom events:
public function onFormSubmit(FormEvent $event, GoogleCaptchaService $captchaService)
{
$result = $captchaService->verify($event->getRequest());
if (!$result->success) {
$event->stopPropagation();
}
}
captcha field type from the bundle for seamless integration:
$builder->add('captcha', CaptchaType::class);
{% set siteKey = app.parameters.google_captcha.site_key %}
<div class="g-recaptcha" data-sitekey="{{ siteKey }}"></div>
google_captcha:
error_message: 'Please complete the reCAPTCHA challenge.'
Missing Frontend Script:
Forgetting to include api.js or using the wrong data-sitekey will cause silent failures. Always verify the frontend widget renders correctly.
Secret Key Exposure:
Hardcoding GOOGLE_CAPTCHA_SECRET in config files (instead of .env) risks leaks. Use %env() strictly.
Rate Limiting: Google may temporarily block requests during testing. Use the reCAPTCHA test keys for development.
IP-Based Bans:
Aggressive testing (e.g., automated scripts) may trigger IP bans. Use the v3 API for non-intrusive validation if needed.
Caching Issues: The bundle does not cache responses by default. For high-traffic sites, implement a short-lived cache (e.g., Redis) for verification results.
g-recaptcha-response field is included in the request. Use:
$response = $request->request->get('g-recaptcha-response');
verify() method returns an object with success (bool) and error-codes (array). Log these for debugging:
error_log(print_r($result, true));
03AHJ...) to verify backend logic:
$request->request->set('g-recaptcha-response', '03AHJ...');
Custom Verification Logic:
Extend the GoogleCaptchaService to add business rules:
class CustomCaptchaService extends GoogleCaptchaService
{
public function verify(Request $request, int $minScore = 0.9)
{
$result = parent::verify($request);
if ($result->success && $result->score < $minScore) {
$result->success = false;
$result->errorCodes[] = 'score_too_low';
}
return $result;
}
}
Async Validation: Offload verification to a queue (e.g., Symfony Messenger) for performance:
$message = new VerifyCaptchaMessage($request->get('g-recaptcha-response'));
$this->messageBus->dispatch($message);
Multi-Recaptcha Support: Use the bundle’s service container to manage multiple reCAPTCHA instances (e.g., for different domains):
services:
app.google_captcha.admin:
class: BeckUp\GoogleCaptchaBundle\Service\GoogleCaptchaService
arguments:
- '%env(GOOGLE_CAPTCHA_ADMIN_SECRET)%'
Fallback Mechanisms: Implement a fallback (e.g., honeypot) when reCAPTCHA fails:
if (!$result->success && $this->honeypot->isValid($request)) {
// Allow submission
}
GOOGLE_CAPTCHA_SECRET in .env. For multi-environment setups, use:
GOOGLE_CAPTCHA_SECRET=%env(GOOGLE_RECAPTCHA_SECRET_%kernel.environment%)%
verifyToken() (if present) in favor of verify() for consistency with Google’s API.google_captcha:
debug: '%kernel.debug%'
How can I help you explore Laravel packages today?