带有 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 class,但我也不完全确定这是否是最佳选择。

看起来 logInUser() 方法是添加自定义更改的地方,因为它实际上设置了令牌,但话又说回来,如果有更聪明的方法来做到这一点,我肯定会选择它。

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

请注意这是序列化的事实,并确保在需要时存储对象以实现 serialize/unserialize 方法,以免出现循环引用问题。

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

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

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

您也可以使用以下代码作为指导。

在服务 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');
   }

}

希望对您有所帮助,

亚历山德鲁·科索伊