我们的项目使用带有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