Redirect response from Event Subscriber in Symfony PHP

9.3k Views Asked by At

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?

4

There are 4 best solutions below

1
On BEST ANSWER

Should be something like:

$event->setResponse(new RedirectResponse($route));
0
On

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

0
On

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();
2
On

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

$event->setController(function() use ($redirectUrl) {
    return new RedirectResponse($redirectUrl);
});