Skip to content

Instantly share code, notes, and snippets.

@Burgov
Last active August 12, 2023 03:32
Show Gist options
  • Save Burgov/7300028 to your computer and use it in GitHub Desktop.
Save Burgov/7300028 to your computer and use it in GitHub Desktop.
CSRF protection for AJAX requests
<?php
namespace myApp\APIBundle\Http;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class CSRFListener implements EventSubscriberInterface
{
private $provider;
public static function getSubscribedEvents()
{
return array(
'kernel.request' => array('onKernelRequest', 1000),
'kernel.response' => 'onKernelResponse'
);
}
public function __construct(CsrfProviderInterface $provider)
{
$this->provider = $provider;
}
public function onKernelRequest(GetResponseEvent $e)
{
if (in_array($e->getRequest()->getMethod(), array('POST', 'PUT', 'DELETE', 'PATCH')) && $e->getRequest()->isXmlHttpRequest()) {
if (!$this->provider->isCsrfTokenValid('ajax', $e->getRequest()->headers->get('x-xsrf-token'))) {
$e->setResponse(new Response('The XSRF token is invalid', 412));
return;
}
}
}
public function onKernelResponse(FilterResponseEvent $e)
{
if ($e->getRequest()->isMethod('GET') && !$e->getRequest()->isXmlHttpRequest()) {
$e->getResponse()->headers->setCookie(new Cookie('xsrf-token', $this->provider->generateCsrfToken('ajax'), 0, '/', null, false, false));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment