简体   繁体   English

Symfony2登录事件侦听器和security.interactive_login事件从未使用FOSUser触发

[英]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. 我正在尝试添加一个Symfony2登录事件监听器,目标是在每个请求上记录用户时设置数据库存储的语言环境,并回退到没有用户登录的默认语言环境。 I use FOSUserBundle, and I'm trying to get the security.interactive_login event to work. 我使用FOSUserBundle,我试图让security.interactive_login事件起作用。 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/ 我在互联网上找到了很多像这样的代码: 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: 我有自己的FOSUserBundle子包和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. 问题是,即使在记录时,也永远不会触发security.interactive_login事件。 On the contrary, my setLocaleForUnauthenticatedUser is always trigered. 相反,我的setLocaleForUnauthenticatedUser总是被触发。 Every code sample I found seems to work fluenty, what's wrong with my app? 我找到的每个代码示例似乎都很流畅,我的应用程序出了什么问题?

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: 在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 }]

same problem here. 同样的问题在这里 But the problem is not that event is not triggered. 但问题不在于没有触发事件。 The problem is that after redirecting, the request locale is lost. 问题是重定向后,请求区域设置丢失。 With the help from this link: 在此链接的帮助下:

Changing locale with symfony 2.1 使用symfony更改语言环境2.1

(And based on this ) (并基于

I figured out how to solve it. 我想出了如何解决它。 In the UserListener: 在UserListener中:

class UserListener
{
    private $session;

    public function setSession($session) {
        $this->session = $session;
    }    

    public function setLocaleForUnauthenticatedUser(GetResponseEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
            return;
        }
        $request = $event->getRequest();
        if ('undefined' == $request->getLocale()) {
            if($locale = $request->getSession()->get('_locale')) {
                $request->setLocale($locale);
            } else {
                $request->setLocale($request->getPreferredLanguage());
            }
        }
    }

    public function setLocaleForAuthenticatedUser(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();

        if ($locale = $user->getLocale()) {
//            $event->getRequest()->setLocale($user->getLocale());
            $this->session->set('_locale', $locale);
        }
    }
}

In services.yml, you should declare: 在services.yml中,您应该声明:

your_listener_name:
    class: ...\UserBundle\EventListener\UserListener
    calls:
        - [ setSession, ['@session'] ]
    tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM