Symfony
TrustCaptcha – Bot protection

Symfony CAPTCHA Integration

Wire TrustCaptcha into a Symfony controller — or, even cleaner, into a custom Validator constraint — in just a few lines of PHP. Stop bot-driven spam on logins, signups and contact forms while keeping CSRF, Twig and the Form component intact. EU-hosted, GDPR-ready, no image puzzles.

Quickstart

How the integration works

1. Create a CAPTCHA

Create a user account or log in with an existing one. Then create a new CAPTCHA or select an existing one. If you’re unsure whether TrustCaptcha is right for you, try our CAPTCHA service risk-free for 14 days at no cost.

On the CAPTCHA overview page, you will find all the important information, such as the site key and licence key, and you can also create your API key. Allow your websites to access your CAPTCHA by simply adding them to the access authorised domain list in the CAPTCHA security rules.

Start of the CAPTCHA creation form.
CAPTCHA security rules of a demo CAPTCHA.

2. Add the CAPTCHA widget to your Twig template

Drop the TrustCaptcha widget into the Twig template that renders your form. The widget runs the CAPTCHA in the background and adds a hidden tc-verification-token field on submit, which arrives on $request->request like any other input.

templates/contact/index.html.twig
HTML
<script type="module" src="https://cdn.trustcomponent.com/trustcaptcha/3.0.x/trustcaptcha.esm.min.js"></script>

<form method="post" action="{{ path('contact_submit') }}">
    <input type="hidden" name="_token" value="{{ csrf_token('contact') }}">
    <input type="email" name="email" required>
    <trustcaptcha-component sitekey="<your_site_key>"></trustcaptcha-component>
    <button type="submit">Send</button>
</form>

The CAPTCHA widget will then be displayed inside your form:

CAPTCHA done

Need detailed information about the CAPTCHA widget integration?
For the full widget reference — including themes, languages, custom design and more — please read our documentation.

Read the documentation

3. Validate the token in your Symfony controller

In your Symfony controller, take the verification token from the request, look up the result via our PHP library, and decide whether to accept the request.

First, install our TrustCaptcha PHP library:

Install
bash
composer require trustcomponent/trustcaptcha-php:^3.0

Then validate the token inside your controller and act on the result:

ContactController.php
PHP
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use TrustComponent\TrustCaptcha\TrustCaptcha;

class ContactController extends AbstractController
{
    #[Route('/contact', name: 'contact_submit', methods: ['POST'])]
    public function submit(Request $request): Response
    {
        $token = $request->request->get('tc-verification-token', '');

        try {
            $trustCaptcha = new TrustCaptcha('<your_api_key>');
            $result = $trustCaptcha->getVerificationResult($token);
        } catch (\Throwable $e) {
            return $this->render('contact/index.html.twig', ['error' => 'CAPTCHA verification failed.']);
        }

        if (!$result->verificationPassed || $result->score > 0.5) {
            return $this->render('contact/index.html.twig', ['error' => 'CAPTCHA verification failed.']);
        }

        // CAPTCHA passed — process the request
        return $this->redirectToRoute('contact_success');
    }
}

Need detailed information about the Symfony CAPTCHA integration?
For full step-by-step instructions — including a reusable custom Validator constraint for projects with several protected endpoints — please read our documentation.

Read the documentation

Other backend framework instead of Symfony?
If you use a different framework, pick the matching recipe here. If your framework isn’t listed, your software developers can integrate the verification themselves using our documentation or ask our support team for a pre-built integration.

Actix Web
ASP.NET Core
Axum
Django
Echo
Express
FastAPI
Fastify
Fiber
Flask
Gin
Hapi
Laravel
Micronaut
NestJS
Next.js
Quarkus
Ruby on Rails
Sinatra
Spring Boot
Symfony

4. Congratulations 🎉

You are now protected by TrustCaptcha - congratulations!

CAPTCHA done

FAQs

Where in a Symfony app does the CAPTCHA verification go?
Inside the controller method that receives the form submission, before persisting any entity or sending mail. The CAPTCHA token comes in as a regular request parameter — read it with $request->request->get('tc-verification-token').
Can I plug the CAPTCHA check into Symfony's Validator?
Yes — that's the cleanest pattern. Build a custom constraint (App\Validator\TrustCaptchaToken) and a tagged ConstraintValidator that calls our PHP library. Inject ValidatorInterface into the controller and call $validator->validate($token, new TrustCaptchaToken()).
Does Symfony's Form component bind the widget's hidden token automatically?
Not directly. The widget posts tc-verification-token as a top-level field, but Form types nest fields under the form's block prefix (e.g. contact_form[tc-verification-token]). The simplest path is to validate the token via ValidatorInterface as shown in our guide, alongside $form->handleRequest($request).
Does TrustCaptcha replace Symfony's CSRF protection?
No. CSRF protection and TrustCaptcha are independent layers — both should stay enabled. Keep csrf_token() in your Twig template and CSRF in your Form types. The CAPTCHA only confirms that a human submitted the form.
Where should I store the CAPTCHA API key?
Add TRUSTCAPTCHA_API_KEY to your .env file and bind it to a parameter in services.yaml: trustcaptcha.api_key: '%env(TRUSTCAPTCHA_API_KEY)%'. Then inject the parameter into your custom validator via the service definition.
Losing leads to CAPTCHAs?

TrustCaptcha blocks spam and bots, not customers. No puzzles, GDPR-ready, EU-hosted.

CAPTCHA start
CAPTCHA done
Puzzle-free UX
Runs in the background while visitors type — so more people finish your forms and fewer drop off.
GDPR-ready
EU-hosted and privacy-first: no cookies, encrypted transmission, automatic cleanup — with ready-to-use legal resources.
Multi-layer Security
Adaptive protection plus intelligent risk scoring stops abuse early — even when attack traffic spikes.
Full Control
Fine-tune sensitivity, set allow/block lists, and use geoblocking — you decide how strict verification should be.

Protect your Symfony application with TrustCaptcha in just a few steps!

  • EU-hosted & GDPR-ready
  • No puzzles
  • Try free for 14 days