We want to redirect to a path or another after login. Also we need to pass de language in this path.
We have a Login Listener as a service to check this. Our problem is to do the redirect accion.
Code:
<service id="acme.login_listener" class="acme\DemoBundle\Listener\LoginListener">
<tag name="kernel.event_listener" event="security.interactive_login" method="onSecurityInteractiveLogin" priority="-1" />
<tag name="kernel.event_listener" event="filter.response" method="onKernelResponse" />
<argument type="service" id="service_container" />
<argument type="service" id="router" />
</service>
The listener code:
namespace Acme\DemoBundle\Listener;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
class LoginListener
{
protected $container;
protected $router;
public function __construct(ContainerInterface $container, Router $router)
{
$this->container = $container;
$this->router = $router;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$token = $event->getAuthenticationToken();
$request = $event->getRequest();
$username = $token->getUsername();
$em = $this->container->get('doctrine')->getEntityManager();
$user = $em->getRepository('acmeDemoBundle:User')->findOneByUsername($username);
$locale = strtolower($user->getUsuari()->getIdioma()->getCodi6391());
$locale = 'ca'; //force locale test
$session = $request->getSession();
$session->setLocale($locale);
$session->set('idioma', $locale);
$session->set('_locale', $locale);
$session->set('locale', $locale);
$url = $this->router->generate('onePath', array('_locale' => $locale));
//$event->setResponse(new RedirectResponse($url));
//$event->stopPropagation();
//echo $url;exit;
$response = new RedirectResponse($url);
return $response;
...
Our problem is to do the redirect to the wished path in onSecurityInteractiveLogin function.
We tried to do the $event->setResponse but it doesn’t work. This $event var doesn’t have this method.
Any idea?
Thanks for your help.
Edited: second option (Jan 27, 2012)
Following: http://www.reecefowell.com/2011/10/26/redirecting-on-loginlogout-in-symfony2-using-loginhandlers/
I tried to use Handlers. I configured the services.xml:
<service id="company.login_success_handler" class="project\demoBundle\Handler\LoginSucessHandler">
<tag name="monolog.logger" channel="project" />
<argument type="service" id="logger" />
<argument type="service" id="router" />
</service>
ON security.yml:
firewalls:
main:
pattern: /.*
form_login:
check_path: /login_check
login_path: /login
success_handler: company.login_success_handler
use_forward: false
And in Symfony/src/project/demoBundle/Handler/loginSuccessHandler.php
<?php
namespace project\demoBundle\Handler;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{
protected $router;
protected $security;
public function __construct(Router $router, SecurityContext $security)
{
$this->router = $router;
$this->security = $security;
echo "hello world";exit;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
echo "hello world 2";exit;
if ($this->security->isGranted('ROLE_SUPER_ADMIN'))
{
$response = new RedirectResponse($this->router->generate('category_index'));
}
elseif ($this->security->isGranted('ROLE_ADMIN'))
{
$response = new RedirectResponse($this->router->generate('category_index'));
}
elseif ($this->security->isGranted('ROLE_USER'))
{
// redirect the user to where they were before the login process begun.
$referer_url = $request->headers->get('referer');
$response = new RedirectResponse($referer_url);
}
return $response;
}
}
But if I execute the web app, it doesn’t into at this function and doesn’t show “Hello world”.
Do you know what I’m doing bad?
Thank you!
I found the UrlGeneratorInterface used in FOSUserBundle
FosUserBundle Hooking into controllers