8

I'm trying to return a permanent (301) redirect response from a event subscriber hooked into the kernel events in Synfony PHP.

My subscriber is as follow:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

use Symfony\Component\HttpFoundation\RedirectResponse;

class KernelSubscriber implements EventSubscriberInterface {

    public function __construct() {

        // some stuff here but not relevant for this example
    }

    public static function getSubscribedEvents(): array {

        return [ KernelEvents::REQUEST => 'onRequest' ];
    }

    public function onRequest(GetResponseEvent $event): void {

        // if conditions met
        //     301 redirect to some internal or external URL

        if(!$event->isMasterRequest()) return;
    }   
}

If this were a controller I would return $this->redirectToRoute('route') or something like that but returning from the onRequest method is in a much different context.

How can I return a response (a redirect, in particular) from this event subscriber?

yevg
  • 1,846
  • 9
  • 34
  • 70

4 Answers4

19

Should be something like:

$event->setResponse(new RedirectResponse($route));
Alex.Barylski
  • 2,843
  • 4
  • 45
  • 68
  • It tells me: `No route found for "GET http://localhost:8000/home" (from "http://localhost:8000/login")`. How can I get that `$route` ?? – David Davó Apr 16 '22 at 10:21
3

In my case the event had no setResponse method, but I could use the send method from the Response class.

$response = new RedirectResponse('https://stackoverflow.com/', 302);
$response->send();
Dennis
  • 59
  • 1
  • 4
1

For me what worked was to inject the urlGenerator and then check for the user token and make a new RedirectResponse to my logout ourl.

public function onKernelController(ControllerEvent $event)
{
    if (!$event->isMainRequest()) {
        return;
    }

    $session = $event->getRequest()->getSession();
    $ssoSessionTime = $session->get('sso.expiration_time');
    if (($ssoSessionTime - time()) < 0) {
        $logoutUrl = $this->urlGenerator->generate('logout');
        $response = new RedirectResponse($logoutUrl);
        return $response->send();
    }
}

Here I check that the timestamp given by my authenticator is not smaller than current time. If it is I send a new RedirectResponse

Simon Berton
  • 468
  • 5
  • 13
0

Use the below method to set the redirect response / redirect url.

$event->setController(function() use ($redirectUrl) {
    return new RedirectResponse($redirectUrl);
});
Faizan Noor
  • 846
  • 10
  • 11