I'm having problems getting a redirect after login to work in Symfony.
It works for some pages but for others, the last_route
session variable is being set to a users profile picture that uses the liip_imagine_filter:
"last_route" => [
"name" => "liip_imagine_filter",
"params" => [
"filter" => "profile_picture"
"path" => "frederick-jacobson/5ba60fc93056b.png"
]
]
LoginFormAuthenticator:
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
/*...*/
protected function getDefaultSuccessRedirectURL()
{
/** @var Session $session */
$session = $this->container->get('session');
$priorPage = $session->get('last_route');
return $this->router->generate($priorPage['name'], $priorPage['params']);
// return $this->router->generate('poll_index');
}
}
This means that it tries to redirect to an image URL.
services.yml:
poll.last_route_event_listener:
class: PollBundle\Services\LastRouteListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 30 }
LastRouteListener:
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
class LastRouteListener
{
public function onKernelRequest(GetResponseEvent $event)
{
// Do not save subrequests
if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
return;
}
$request = $event->getRequest();
$session = $request->getSession();
$routeName = $request->get('_route');
$routeParams = $request->get('_route_params');
if ($routeName[0] == '_') {
return;
}
$routeData = ['name' => $routeName, 'params' => $routeParams];
// Do not save same matched route twice
$thisRoute = $session->get('this_route', []);
if ($thisRoute == $routeData) {
return;
}
$session->set('last_route', $thisRoute);
$session->set('this_route', $routeData);
}
}
Can someone please help me work out what I'm doing wrong and/or tell me the correct way to handle redirecting to the page prior to login?
As pointed out in the comments below my question. I was using a custom listener that was picking up the liip_imagine_filter
route and setting it to the last_route
session variable.
I could just add a check in to the listener, like this:
if ($routeName[0] == '_' || $routeName == 'liip_imagine_filter') {
return;
}
But a better way to handle it is to use the built in Symfony\Component\Security\Http\Util\TargetPathTrait
It is usually set automatically when a user hits a restricted page, but it can be set manually with $this->saveTargetPath($request->getSession(), $providerKey, $request->getUri());
Then you can use $targetPath
to find the route to redirect to in LoginFormAuthenticator
:
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
/*...*/
use TargetPathTrait;
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$targetPath = $this->getTargetPath($request->getSession(), $providerKey);
if (!$targetPath || $request->getBaseUrl() && !strpos($targetPath, $request->getBaseUrl())) {
$targetPath = $this->container->get('router')
->generate('poll_index');
}
return new RedirectResponse($targetPath);
}
}