带有 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');
}
}
希望对您有所帮助,
亚历山德鲁·科索伊
我们的项目使用带有 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');
}
}
希望对您有所帮助,
亚历山德鲁·科索伊