Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 login event listener and security.interactive_login event never triggered using FOSUser

I'm trying to add a Symfony2 login event listener, the goal is to set a database-stored locale if the user is logged, on each request, and to fallback to a default one of there is no user logged. I use FOSUserBundle, and I'm trying to get the security.interactive_login event to work. I find a lot of code over the internet like this one: http://dev.dbl-a.com/symfony-2-0/how-to-add-a-symfony2-login-event-listener/

I have my own child bundle of the FOSUserBundle and this implementation in services.yml:

my_user.security.interactive_login_listener:
        class: My\UserBundle\EventListener\UserListener
        arguments: [@security.context, @doctrine]
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }

my_user.security.kernel_request_listener:
        class: My\UserBundle\EventListener\UserListener
        arguments: [@security.context, @doctrine]
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: setLocaleForUnauthenticatedUser }

Problem is, the security.interactive_login event is never triggered, even when logging, even when logged. On the contrary, my setLocaleForUnauthenticatedUser is always trigered. Every code sample I found seems to work fluenty, what's wrong with my app?

like image 485
Dolorf Avatar asked Dec 20 '12 13:12

Dolorf


1 Answers

Figured out too, and did more or less the same work around: There is no problem indeed, but there is some kind of redirection after login, so the profiler never show the actual request who trigger the interactive login listener.

use Symfony\Component\Security\Http\Event\InteractiveLoginEvent,
    Symfony\Component\Security\Http\Event\FilterControllerEvent,
    Symfony\Component\HttpKernel\Event\GetResponseEvent,
    Symfony\Component\HttpKernel\HttpKernelInterface;
use FOS\UserBundle\Entity\User as BaseUser;

class LocaleListener {

    protected $container;
    protected $availableLocales;

    public function __construct(\Symfony\Component\DependencyInjection\Container $container, $availableLocales) {
        $this->container = $container;
        $this->availableLocales = $availableLocales;
    }

    public function onKernelRequest(GetResponseEvent $event) {
        $request = $event->getRequest();
        $locale = $request->getPreferredLanguage($this->availableLocales);
        $session = $request->getSession();

        $token = $this->container->get('security.context')->getToken();
        if( is_object( $token ) ) {
            $user = $token->getUser();
            if ($user instanceof BaseUser) {
                $locale = $user->getLocale();
            }
        }

        $session = $this->container->get('session');
        $session->set('_locale', $locale);
        $request->setLocale($locale);
    }
 }

In services.yml:

user.locales.kernel_request_listener:
        class: Acme\UserBundle\EventListener\LocaleListener
        arguments: [ @service_container, [ 'en', 'fr', 'ru' ] ]
        tags: [{ name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: -255 }]
like image 65
Dolorf Avatar answered Oct 05 '22 11:10

Dolorf