captcha-com/symfony-captcha-bundle
Installation
composer require captcha-com/symfony-captcha-bundle
Add to config/bundles.php:
return [
// ...
Captcha\Symfony\CaptchaBundle::class => ['all' => true],
];
Configuration Publish the default config:
php bin/console config:dump-reference CaptchaSymfonyCaptchaBundle
Update config/packages/captcha.yaml with your BotDetect API key (free tier available).
First Use Case Generate a CAPTCHA in a controller:
use Captcha\Symfony\CaptchaManager;
public function showForm(CaptchaManager $captchaManager)
{
$captcha = $captchaManager->create('MyCaptcha');
return $this->render('form.html.twig', [
'captcha' => $captcha->getHtml(),
]);
}
Render in Twig:
{{ captcha }}
Form Integration Validate CAPTCHA in a form type:
use Captcha\Symfony\Validator\Constraints as CaptchaAssert;
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('email')
->add('captcha', CaptchaType::class, [
'mapped' => false,
'captcha_name' => 'ContactFormCaptcha',
]);
}
}
Add validation constraint:
use CaptchaAssert\ValidCaptcha;
#[ValidCaptcha('ContactFormCaptcha')]
public $captcha;
Dynamic CAPTCHA Generation Generate CAPTCHAs per-user or per-action:
$captchaManager->create('UserRegistration_' . $userId);
API-Based Validation Validate CAPTCHA responses without forms:
$isValid = $captchaManager->validate('MyCaptcha', $userInput);
Captcha\Symfony\CaptchaManager to inject custom themes:
# config/packages/captcha.yaml
captcha:
themes:
custom: '%kernel.project_dir%/public/captcha/themes/custom'
# config/packages/framework.yaml
framework:
rate_limits:
captcha:
limit: 5/minute
CaptchaGeneratedEvent) to log or analyze CAPTCHA usage:
use Captcha\Symfony\Event\CaptchaGeneratedEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
#[AsEventListener(event: CaptchaGeneratedEvent::class)]
public function onCaptchaGenerated(CaptchaGeneratedEvent $event) {
// Log or track CAPTCHA generation
}
API Key Misconfiguration
captcha.yaml to log errors:
captcha:
debug: true
Captcha Name Collisions
captcha_name across forms can cause validation failures.ContactFormCaptcha, LoginFormCaptcha).Caching Headaches
$captchaManager->clear('MyCaptcha');
Twig Template Overrides
# config/packages/captcha.yaml
captcha:
templates:
default: 'bundles/yourbundle/captcha/default.html.twig'
X-Requested-With or other headers aren’t blocking CAPTCHA requests.captcha:
logging: true
Custom Validators Extend the default validator to add business logic:
use Captcha\Symfony\Validator\CaptchaValidator;
class CustomCaptchaValidator extends CaptchaValidator
{
public function validate($value, Constraint $constraint)
{
// Custom logic (e.g., blacklist certain CAPTCHAs)
return parent::validate($value, $constraint);
}
}
Register in services.yaml:
Captcha\Symfony\Validator\CaptchaValidator:
alias: App\Validator\CustomCaptchaValidator
Async Validation Offload CAPTCHA validation to a background job (e.g., Symfony Messenger):
use Captcha\Symfony\Message\ValidateCaptchaMessage;
$bus->dispatch(new ValidateCaptchaMessage('MyCaptcha', $userInput));
Multi-Factor CAPTCHA
Combine with other security layers (e.g., Symfony’s VoteListener):
use Symfony\Component\Security\Http\AccessMapInterface;
class CaptchaAccessMap implements AccessMapInterface
{
public function getAccessRules()
{
return [
'ROLE_ADMIN' => null,
'ROLE_USER' => 'captcha.validate',
];
}
}
How can I help you explore Laravel packages today?