7

我正在尝试添加一个 Symfony2 登录事件侦听器,目标是在用户登录时设置数据库存储的区域设置,在每个请求上,并回退到没有用户登录的默认设置。我使用 FOSUserBundle,并试图让 security.interactive_login 事件起作用。我在互联网上找到了很多这样的代码:http: //dev.dbl-a.com/symfony-2-0/how-to-add-a-symfony2-login-event-listener/

我有自己的 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 }

问题是,security.interactive_login 事件永远不会被触发,即使在记录时,即使在记录时也是如此。相反,我的 setLocaleForUnauthenticatedUser 总是被触发。我发现的每个代码示例似乎都能流畅运行,我的应用程序有什么问题?

4

2 回答 2

1

也想通了,并且或多或少做了相同的工作:确实没有问题,但是登录后有某种重定向,因此分析器永远不会显示触发交互式登录侦听器的实际请求。

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);
    }
 }

在 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 }]
于 2013-01-06T15:51:16.873 回答
0

同样的问题。但问题不在于没有触发事件。问题是重定向后,请求语言环境丢失了。在此链接的帮助下:

使用 symfony 2.1 更改语言环境

(并基于

我想出了如何解决它。在用户监听器中:

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);
        }
    }
}

在 services.yml 中,您应该声明:

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

希望这可以帮助。

于 2012-12-30T03:20:08.500 回答