Install the Bundle
composer require be-soft/recaptcha-bundle
(Note: The package is forked from excelwebzone/recaptcha-bundle but may have updates. Verify the correct namespace in composer.json.)
Enable the Bundle
Add to config/bundles.php (Symfony 4+):
return [
// ...
BE\Soft\RecaptchaBundle\EWZRecaptchaBundle::class => ['all' => true],
];
Configure reCAPTCHA
Create config/packages/ewz_recaptcha.yaml (or merge into existing):
ewz_recaptcha:
version: 3 # or 2, depending on your Google setup
site_key: "YOUR_SITE_KEY"
secret: "YOUR_SECRET_KEY"
verify_url: "https://www.google.com/recaptcha/api/siteverify" # Default, usually no need to change
First Use Case: Protect a Form Add the Twig extension to your template:
{{ render(ewz_recaptcha_form('contact_form', {'theme': 'light'})) }}
(Replace 'contact_form' with your form type name.)
Validate in your form type:
use BE\Soft\RecaptchaBundle\Form\Type\RecaptchaType;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('recaptcha', RecaptchaType::class, [
'mapped' => false,
'constraints' => [
new \BE\Soft\RecaptchaBundle\Validator\Constraints\IsTrue(),
],
]);
}
// In your form type
$builder->add('recaptcha', RecaptchaType::class, [
'mapped' => false,
'required' => $this->isHighRiskForm(), // Custom logic
]);
{% if isHighRiskForm %}
{{ render(ewz_recaptcha_form('form_name')) }}
{% endif %}
# config/packages/ewz_recaptcha.yaml
ewz_recaptcha:
theme: 'dark' # or 'light'
size: 'compact' # or 'normal'
tabindex: 0
{{ render(ewz_recaptcha_form('form_name', {'attr': {'class': 'custom-class'}})) }}
ewz_recaptcha:
version: 2
public_key: "YOUR_V2_SITE_KEY"
private_key: "YOUR_V2_SECRET_KEY"
type: "image" # or "invisible"
ewz_recaptcha:
version: 3
score_threshold: 0.5 # Minimum score to pass
use BE\Soft\RecaptchaBundle\Validator\RecaptchaValidator;
$validator = new RecaptchaValidator($this->getParameter('ewz_recaptcha.secret'));
$isValid = $validator->validate($request->request->get('recaptcha_response'));
// src/EventListener/RecaptchaListener.php
public function onRecaptchaFail(RecaptchaEvent $event)
{
$this->logger->warning('reCAPTCHA failed for IP: ' . $event->getRequest()->getClientIp());
}
services.yaml:
services:
App\EventListener\RecaptchaListener:
tags:
- { name: 'kernel.event_listener', event: 'ewz_recaptcha.fail', method: 'onRecaptchaFail' }
$builder->add('recaptcha', RecaptchaType::class, [
'label' => 'Verify you are not a robot',
'translation_domain' => 'messages',
]);
# config/packages/security.yaml
framework:
form:
csrf_protection:
enabled: true
ignore_routes:
- recaptcha_verify # Custom route for API calls
{{ ewz_recaptcha_widget('form_name') }}
{% if form.recaptcha.errors|length > 0 %}
<div class="error">{{ form.recaptcha.errors|trans({}, 'messages') }}</div>
{% endif %}
// src/Controller/RecaptchaController.php
public function verify(RecaptchaValidator $validator, Request $request)
{
$response = $validator->validate($request->request->get('token'));
return new JsonResponse(['valid' => $response]);
}
Add a route:
# config/routes.yaml
recaptcha_verify:
path: /api/recaptcha/verify
controller: App\Controller\RecaptchaController::verify
methods: [POST]
version: 3 config with v2 keys (or vice versa) will silently fail.site_key/secret against your Google reCAPTCHA admin.EWZRecaptchaBundle logs:
# config/packages/dev/ewz_recaptcha.yaml
ewz_recaptcha:
debug: true
$cache = $this->container->get('cache.app');
$cachedResponse = $cache->get('recaptcha_' . $token);
if (!$cachedResponse) {
$response = $validator->validate($token);
$cache->set('recaptcha_' . $token, $response, 300);
}
ewz_recaptcha_form or ewz_recaptcha_widget not found in Twig.TwigBundle in config/bundles.php.php bin/console cache:clear
csrf_protection: true.$builder->add('recaptcha', RecaptchaType::class, [
'mapped' => false,
'csrf_protection' => false,
]);
<script src="https://www.google.com/recaptcha/api.js?render={{ ewz_recaptcha_config.site_key }}"></script>
# config/packages/dev/ewz_recaptcha.yaml
ewz_recaptcha:
debug: true
logger:
level: debug
Check logs for:
Recaptcha response: {"success": ...}Recaptcha validation failed: ...How can I help you explore Laravel packages today?