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

nwnhqdif  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(190)

bounty还有2天到期。回答此问题可获得+50声望奖励。Emilie Tossan正在寻找一个答案从一个有信誉的来源:谢谢你帮助我理解这一点。

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

  • contact.html.twig* 文件
  1. {% trans_default_domain 'contact' %}
  2. {% extends 'base.html.twig' %}
  3. {% block main %}
  4. {{ form_start(form, {'attr' : {'id' : 'contactform', 'novalidate' : 'novalidate'}} ) }}
  5. {{ form_widget(form.name) }}
  6. {{ form_label(form.name, 'contact.name' | trans ) }}
  7. {{ form_widget(form.email) }}
  8. {{ form_label(form.email, 'contact.email' | trans ) }}
  9. {{ form_widget(form.message) }}
  10. {% for message in app.flashes('captcha') %}
  11. <p class="text-danger">{{ 'contact.error.captcha' | trans }}</p>
  12. {% endfor %}
  13. {{ form_widget(form.save, {'label': 'contact.send' | trans } ) }}
  14. {{ form_end(form) }}
  15. <script>
  16. function renderReCaptcha(widget) {
  17. var form = widget.closest('form');
  18. var widgetType = widget.getAttribute('data-type');
  19. var widgetParameters = {
  20. 'sitekey': '{{ gg_recaptcha_site_key }}'
  21. };
  22. if (widgetType == 'invisible') {
  23. widgetParameters['callback'] = function () {
  24. form.submit()
  25. };
  26. widgetParameters['size'] = "invisible";
  27. }
  28. var widgetId = grecaptcha.render(widget, widgetParameters);
  29. if (widgetType == 'invisible') {
  30. bindChallengeToSubmitButtons(form, widgetId);
  31. }
  32. }
  33. function bindChallengeToSubmitButtons(form, reCaptchaId) {
  34. getSubmitButtons(form).forEach(function (button) {
  35. button.addEventListener('click', function (e) {
  36. e.preventDefault();
  37. grecaptcha.execute(reCaptchaId);
  38. });
  39. });
  40. }
  41. function getSubmitButtons(form) {
  42. var buttons = form.querySelectorAll('button, input');
  43. var submitButtons = [];
  44. for (var i= 0; i < buttons.length; i++) {
  45. var button = buttons[i];
  46. if (button.getAttribute('type') == 'submit') {
  47. submitButtons.push(button);
  48. }
  49. }
  50. return submitButtons;
  51. }
  52. </script>
  53. {% endblock %}

字符串

  • ContactController.php* 文件
  1. <?php
  2. namespace App\Controller\Front;
  3. use App\Form\Front\ContactType;
  4. use Symfony\Component\Mime\Email;
  5. use App\Repository\UserRepository;
  6. use App\Form\Front\ContactFromUserType;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\Mailer\MailerInterface;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\Routing\Annotation\Route;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. class ContactController extends AbstractController
  13. {
  14. #[Route('/contact', name: 'contact')]
  15. public function contact(
  16. Request $request,
  17. UserRepository $userRepository,
  18. MailerInterface $mailer): Response
  19. {
  20. $form = $this->createForm(ContactType::class);
  21. $form->handleRequest($request);
  22. if ($form->isSubmitted() && $form->isValid()) {
  23. $contactFormData = $form->getData();
  24. if ($contactFormData['captcha'] == []) {
  25. $this->addFlash('captcha', 'Si tu n\'es pas un robot, coche la case.');
  26. } else {
  27. $message = (new Email())
  28. ->from($contactFormData['email'])
  29. ->to('contact@mail.com')
  30. ->subject('Message d\'un visiteur !')
  31. ->text(
  32. '"'.$contactFormData['message'].'"'.\PHP_EOL.\PHP_EOL.
  33. $contactFormData['name'].' - '.$contactFormData['email'],
  34. 'text/plain'
  35. );
  36. $mailer->send($message);
  37. }
  38. }
  39. return $this->render('front/home/contact.html.twig', [
  40. 'form' => $form->createView()
  41. ]);
  42. }
  43. }


我注意到每一个案例$contactFormData['captcha'] == []

  • ReCaptchaValidationListener.php* 文件
  1. <?php
  2. namespace App\Form\EventListener;
  3. use ReCaptcha\ReCaptcha;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\Form\FormError;
  6. use Symfony\Component\Form\FormEvent;
  7. use Symfony\Component\Form\FormEvents;
  8. use Symfony\Component\HttpFoundation\Request;
  9. class ReCaptchaValidationListener implements EventSubscriberInterface
  10. {
  11. private $reCaptcha;
  12. public function __construct(ReCaptcha $reCaptcha)
  13. {
  14. $this->reCaptcha = $reCaptcha;
  15. }
  16. public static function getSubscribedEvents()
  17. {
  18. return [
  19. FormEvents::POST_SUBMIT => 'onPostSubmit'
  20. ];
  21. }
  22. public function onPostSubmit(FormEvent $event)
  23. {
  24. $request = Request::createFromGlobals();
  25. $result = $this->reCaptcha
  26. ->setExpectedHostname($request->getHost())
  27. ->verify($request->request->get('g-recaptcha-response'), $request->getClientIp());
  28. if (!$result->isSuccess()) {
  29. $event->getForm()->addError(new FormError('The captcha is invalid. Please try again.'));
  30. }
  31. }
  32. }


是否有解决方案在我的控制器中写入此条件:* 提交表单时是否勾选了reCAPTCHA robot *?

oknwwptz

oknwwptz1#

是的,有一个解决方案可以在控制器中写入此条件。您可以使用g-recaptcha-response请求参数来检查用户是否勾选了reCAPTCHA复选框。如果此参数的值为空,则用户尚未勾选复选框。
下面是如何在控制器中执行此操作的示例:

  1. public function contact(Request $request)
  2. {
  3. $form = $this->createForm(ContactType::class);
  4. $form->handleRequest($request);
  5. if ($form->isSubmitted() && $form->isValid()) {
  6. $contactFormData = $form->getData();
  7. $gRecaptchaResponse = $request->request->get('g-recaptcha-response');
  8. if (empty($gRecaptchaResponse)) {
  9. $this->addFlash('captcha', 'If you \'re not a robot, check the box.');
  10. } else {
  11. // The user has ticked the reCAPTCHA checkbox.
  12. }
  13. }
  14. return $this->render('front/home/contact.html.twig', [
  15. 'form' => $form->createView()
  16. ]);
  17. }

字符串

说明:

我们首先检查表格是否已提交且有效。如果是,我们就得到g-recaptcha-response请求参数的值。如果值为空,那么我们知道用户没有勾选reCAPTCHA复选框。然后,我们可以向会话中添加一条flash消息,通知用户他们需要勾选复选框。
如果g-recaptcha-response请求参数的值不为空,那么我们知道用户已经勾选了reCAPTCHA复选框。然后,我们可以在控制器中继续执行任何其他逻辑。

展开查看全部

相关问题