如何在 Symfony 控制器中检查 reCAPTCHA 的勾选?

问题描述 投票:0回答:0

我想知道是否可以在控制器 php 中专门检查 reCAPTCHA 的勾选。我想这样做,以便我可以设定一个条件,以便在用户没有勾选“我不是机器人”复选框的情况下显示错误消息。

我尝试做这样的事情:

contact.html.twig 文件

{% trans_default_domain 'contact' %}

{% extends 'base.html.twig' %}

{% block main %}

{{ form_start(form, {'attr' : {'id' : 'contactform', 'novalidate' : 'novalidate'}} ) }}

{{ form_widget(form.name) }}
{{ form_label(form.name, 'contact.name' | trans ) }}

{{ form_widget(form.email) }}
{{ form_label(form.email, 'contact.email' | trans ) }}

{{ form_widget(form.message) }}
            
{% for message in app.flashes('captcha') %}
    <p class="text-danger">{{ 'contact.error.captcha' | trans }}</p>
{% endfor %}

{{ form_widget(form.save, {'label': 'contact.send' | trans } ) }}

{{ form_end(form) }}

<script>

    function renderReCaptcha(widget) {
        var form = widget.closest('form');
        var widgetType = widget.getAttribute('data-type');
        var widgetParameters = {
            'sitekey': '{{ gg_recaptcha_site_key }}'
        };

        if (widgetType == 'invisible') {
            widgetParameters['callback'] = function () {
                form.submit()
            };
            widgetParameters['size'] = "invisible";
        }

        var widgetId = grecaptcha.render(widget, widgetParameters);

        if (widgetType == 'invisible') {
            bindChallengeToSubmitButtons(form, widgetId);
        }
    }

    function bindChallengeToSubmitButtons(form, reCaptchaId) {
        getSubmitButtons(form).forEach(function (button) {
            button.addEventListener('click', function (e) {
                e.preventDefault();
                grecaptcha.execute(reCaptchaId);
            });
        });
    }

    function getSubmitButtons(form) {
        var buttons = form.querySelectorAll('button, input');
        var submitButtons = [];

        for (var i= 0; i < buttons.length; i++) {
            var button = buttons[i];
            if (button.getAttribute('type') == 'submit') {
                submitButtons.push(button);
            }
        }
        return submitButtons;
    }

</script>

{% endblock %}

ContactController.php 文件

<?php

namespace App\Controller\Front;

use App\Form\Front\ContactType;
use Symfony\Component\Mime\Email;
use App\Repository\UserRepository;
use App\Form\Front\ContactFromUserType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class ContactController extends AbstractController
{
    #[Route('/contact', name: 'contact')]
    public function contact(
        Request $request, 
        UserRepository $userRepository,
        MailerInterface $mailer): Response
    {
            $form = $this->createForm(ContactType::class);
            $form->handleRequest($request);

            if ($form->isSubmitted() && $form->isValid()) {
                $contactFormData = $form->getData();
                
                if ($contactFormData['captcha'] == []) {
                    $this->addFlash('captcha', 'Si tu n\'es pas un robot, coche la case.');
                } else {
                    $message = (new Email())
                    ->from($contactFormData['email'])
                    ->to('[email protected]')
                    ->subject('Message d\'un visiteur !')
                    ->text(
                        '"'.$contactFormData['message'].'"'.\PHP_EOL.\PHP_EOL.
                        $contactFormData['name'].' - '.$contactFormData['email'],
                        'text/plain'
                    );
                    $mailer->send($message);
                }
            }

            return $this->render('front/home/contact.html.twig', [
                'form' => $form->createView()
            ]);
    }
}

我注意到每种情况

$contactFormData['captcha'] == []

ReCaptchaValidationListener.php 文件

<?php

namespace App\Form\EventListener;

use ReCaptcha\ReCaptcha;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\Request;

class ReCaptchaValidationListener implements EventSubscriberInterface
{
    private $reCaptcha;

    public function __construct(ReCaptcha $reCaptcha)
    {
        $this->reCaptcha = $reCaptcha;
    }

    public static function getSubscribedEvents()
    {
        return [
            FormEvents::POST_SUBMIT => 'onPostSubmit'
        ];
    }

    public function onPostSubmit(FormEvent $event)
    {
        $request = Request::createFromGlobals();

        $result = $this->reCaptcha
            ->setExpectedHostname($request->getHost())
            ->verify($request->request->get('g-recaptcha-response'), $request->getClientIp());

        if (!$result->isSuccess()) {
            $event->getForm()->addError(new FormError('The captcha is invalid. Please try again.'));
        }
    }
}

是否有解决方案可以在我的控制器中写入此条件:如果提交表单时已勾选 reCAPTCHA 机器人

forms symfony recaptcha
© www.soinside.com 2019 - 2024. All rights reserved.