带有FosUserBundle的Symfony 2.5:登录后向全局会话添加数据


Symfony 2.5 with FosUserBundle: Add data to the global session after Login

我们的项目使用带有Symfony 2.5的FOSUserBundle。我们需要在登录后将自定义数据添加到用户会话中,该数据驻留在数据库中并且是动态的,但应该在应用程序中的所有模板和任何地方进行访问。

我正在考虑覆盖/user-bundle/Security中的LoginManager.php类,但我也不完全确定这是否是最好的选择。

看起来logInUser()方法是添加我们的自定义更改的地方,因为它实际上设置了令牌,但话说回来,如果有更聪明的方法,我肯定会使用它。

您可以添加一个安全交互式登录侦听器,在该侦听器中您可以访问存储在会话中的登录令牌。此令牌继承Symfony''Component''Security''Core''Authentication''token''AbstractToken,因此它具有方法"setAttribute($name,$value)"answers"setAttributes(array$attributes)"。基本上,您在该属性中设置的任何内容都将与用户和令牌一起存储在会话中。

只需注意这是序列化的,并确保存储对象以实现serialize/unserialize方法(如果需要),以免出现循环引用问题。

我推荐这种方法,因为它似乎符合您的要求:

  • 令牌已由symfony存储在会话中
  • 令牌已经可以通过容器中的服务"security.context"在任何控制器中访问
  • 使用代码{{app.security.getToken()}},该令牌已可在twitch中访问

有关身份验证事件的更多信息,请查看symfony食谱:http://symfony.com/doc/current/components/security/authentication.html#authentication-事件

此外,您还可以使用以下代码作为指导原则。

在服务yml

security.interactive_login.listener:
        class: %security.interactive_login.listener.class%
        arguments: ['@security.context', '@session']
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

在你的听众

use Symfony'Component'Security'Core'SecurityContextInterface;
use Symfony'Component'HttpFoundation'Session'Session;
use Symfony'Component'Security'Http'Event'InteractiveLoginEvent;
class SecurityListener
{
   public function __construct(SecurityContextInterface $security, Session $session)
   {
      $this->security = $security;
      $this->session = $session;
   }
   public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
   {
        $token = $event->getAuthenticationToken();
        $token->setAttribute('key','some stuff i want later');
   }
}

希望这能有所帮助,

Alexandru Cosoi