src/Form/EventListener/ReCaptchaValidationListener.php line 59

Open in your IDE?
  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. use Symfony\Contracts\Translation\TranslatorInterface;
  10. /**
  11.  * This event subscriber validates the catpcha's response using the google Recaptcha PHP
  12.  * library.
  13.  *
  14.  * @see https://medium.com/@qferrer/securing-your-symfony-forms-with-google-recaptcha-v2-dbfc902b0c50
  15.  *
  16.  * @author jra
  17.  *
  18.  */
  19. class ReCaptchaValidationListener implements EventSubscriberInterface
  20. {
  21.     /**
  22.      * @var \ReCaptcha\ReCaptcha
  23.      */
  24.     private $reCaptcha;
  25.     /**
  26.      * @var \Symfony\Contracts\Translation\TranslatorInterface
  27.      */
  28.     protected $translator;
  29.     /**
  30.      * @var string
  31.      */
  32.     private $invalidMessage 'error.form.captcha_invalid';
  33.     public function __construct(ReCaptcha $reCaptchaTranslatorInterface $translator)
  34.     {
  35.         $this->reCaptcha $reCaptcha;
  36.         $this->translator $translator;
  37.     }
  38.     public static function getSubscribedEvents()
  39.     {
  40.         return [
  41.             FormEvents::POST_SUBMIT => 'onPostSubmit'
  42.         ];
  43.     }
  44.     public function setInvalidMessage($message)
  45.     {
  46.         $this->invalidMessage $message;
  47.         return $this;
  48.     }
  49.     public function onPostSubmit(FormEvent $event)
  50.     {
  51.         $request Request::createFromGlobals();
  52.         // This will trust all proxies
  53.         // @see : https://symfony.com/doc/current/deployment/proxies.html
  54.         $request->setTrustedProxies(['127.0.0.1''REMOTE_ADDR'], Request::HEADER_X_FORWARDED_ALL);
  55.         // Note that DNS resolution on the PHP server must work properly, otherwise reCaptcha will return a 'connection-refused' error
  56.         $result $this->reCaptcha
  57.             ->setExpectedHostname($request->getHost())
  58.             ->verify($request->request->get('g-recaptcha-response'), $request->getClientIp());
  59.         if (!$result->isSuccess()) {
  60.           $errors $result->getErrorCodes();
  61.           $msg $this->translator->trans($this->invalidMessage, ['message' => implode(', '$errors)]);
  62.           $event->getForm()->addError(new FormError($msg));
  63.         }
  64.     }
  65. }