app/Plugin/NZRecaptcha42/Event/RecaptchaEventSubscriber.php line 47

Open in your IDE?
  1. <?php
  2. namespace Plugin\NZRecaptcha42\Event;
  3. use Plugin\NZRecaptcha42\Service\RecaptchaService;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpFoundation\RequestStack;
  6. use Symfony\Component\HttpKernel\Event\RequestEvent;
  7. use Symfony\Component\HttpKernel\KernelEvents;
  8. use Symfony\Component\HttpFoundation\RedirectResponse;
  9. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  10. class RecaptchaEventSubscriber implements EventSubscriberInterface
  11. {
  12.     /**
  13.      * @var RecaptchaService
  14.      */
  15.     private $recaptchaService;
  16.     /**
  17.      * @var RequestStack
  18.      */
  19.     private $requestStack;
  20.     /**
  21.      * @var UrlGeneratorInterface
  22.      */
  23.     private $urlGenerator;
  24.     public function __construct(
  25.         RecaptchaService $recaptchaService,
  26.         RequestStack $requestStack,
  27.         UrlGeneratorInterface $urlGenerator
  28.     ) {
  29.         $this->recaptchaService $recaptchaService;
  30.         $this->requestStack $requestStack;
  31.         $this->urlGenerator $urlGenerator;
  32.     }
  33.     public static function getSubscribedEvents()
  34.     {
  35.         return [
  36.             KernelEvents::REQUEST => ['onKernelRequest'9],
  37.         ];
  38.     }
  39.     public function onKernelRequest(RequestEvent $event)
  40.     {
  41.         if (!$event->isMainRequest()) {
  42.             return;
  43.         }
  44.         $request $event->getRequest();
  45.         
  46.         // POSTリクエストのみ検証
  47.         if ($request->getMethod() !== 'POST') {
  48.             return;
  49.         }
  50.         $route $request->attributes->get('_route');
  51.         $pathInfo $request->getPathInfo();
  52.         
  53.         // 対象ルートとアクションの対応
  54.         $routeConfig = [
  55.             'entry' => ['action' => 'entry''check' => 'isEnabledForEntry''redirect' => 'entry'],
  56.             'mypage_login' => ['action' => 'login''check' => 'isEnabledForLogin''redirect' => 'mypage_login'],
  57.             'contact' => ['action' => 'contact''check' => 'isEnabledForContact''redirect' => 'contact'],
  58.         ];
  59.         // カスタムルート/URLをチェック
  60.         $isCustomTarget $this->recaptchaService->isEnabledForCustomRoute($route$pathInfo);
  61.         if (!isset($routeConfig[$route]) && !$isCustomTarget) {
  62.             return;
  63.         }
  64.         // カスタムルート/URLの場合
  65.         if ($isCustomTarget && !isset($routeConfig[$route])) {
  66.             $token $request->request->get('g-recaptcha-response');
  67.             $action $route ?: str_replace('/''_'trim($pathInfo'/'));
  68.             
  69.             if (!$this->recaptchaService->verify($token$action)) {
  70.                 log_warning('[NZRecaptcha] Blocked custom request', [
  71.                     'route' => $route,
  72.                     'path' => $pathInfo,
  73.                     'ip' => $request->getClientIp(),
  74.                 ]);
  75.                 $session $request->getSession();
  76.                 $session->getFlashBag()->add('eccube.front.error''セキュリティ検証に失敗しました。もう一度お試しください。');
  77.                 $redirectUrl $request->getUri();
  78.                 $event->setResponse(new RedirectResponse($redirectUrl));
  79.             }
  80.             return;
  81.         }
  82.         $config $routeConfig[$route];
  83.         $checkMethod $config['check'];
  84.         // この機能が有効かチェック
  85.         if (!$this->recaptchaService->$checkMethod()) {
  86.             return;
  87.         }
  88.         // reCAPTCHAトークンを取得
  89.         $token $request->request->get('g-recaptcha-response');
  90.         // トークン検証
  91.         if (!$this->recaptchaService->verify($token$config['action'])) {
  92.             log_warning('[NZRecaptcha] Blocked request', [
  93.                 'route' => $route,
  94.                 'ip' => $request->getClientIp(),
  95.             ]);
  96.             $session $request->getSession();
  97.             $session->getFlashBag()->add('eccube.front.error''セキュリティ検証に失敗しました。もう一度お試しください。');
  98.             $redirectUrl $this->urlGenerator->generate($config['redirect']);
  99.             $event->setResponse(new RedirectResponse($redirectUrl));
  100.         }
  101.     }
  102. }