如何在Symfony中记住登录时设置用户区域设置?

时间:2018-04-30 13:06:21

标签: php symfony session authentication local

我正在开发基于Symfony 2.8的项目。该网页可以使用不同的语言,所选语言存储在{​​{1}}中。使用Session类,当用户进入页面或登录时设置正确的语言环境没有问题:

Locale Listener

这与使用登录侦听器扩展的Symfony docs中的代码相同。用户主动登录时效果很好。在这种情况下,class LocaleListener implements EventSubscriberInterface { private $defaultLocale; public function __construct($defaultLocale = 'de') { $this->defaultLocale = $defaultLocale; } public static function getSubscribedEvents() { return array( // must be registered before the default Locale listener KernelEvents::REQUEST => array(array('onKernelRequest', 17)), SecurityEvents::INTERACTIVE_LOGIN => array(array('onSecurityInteractiveLogin', 18)), AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onAuthenticationSuccess', ); } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if (!$request->hasPreviousSession()) return; if ($locale = $request->attributes->get('_locale')) { // try to see if the locale has been set as a _locale routing parameter $request->getSession()->set('_locale', $locale); } else { // if no explicit locale has been set on this request, use one from the session $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); } } public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { // ...get locale from user settings and it info to session... } public function onAuthenticationSuccess(AuthenticationEvent $event) { // ...get locale from user settings and it info to session... } } SecurityEvents::INTERACTIVE_LOGIN都会被触发(BTW:两者之间有什么区别)?

但是,如果用户已登录并访问某个页面,则不会触发这两个事件。

当会话过期且AuthenticationEvents::AUTHENTICATION_SUCCESS cookie不存在时,这是一个问题。在我几天没有使用该计算机后,我在浏览器中刷新页面时遇到了问题:remember_me cookie仍然处于活动状态,因此用户仍然登录。但是页面在默认情况下刷新了语言,而不是用户语言,这只有在会话过期时才有可能...

我没有在配置文件中配置会话生命周期,Symfony调试工具栏显示会话生命周期为0.当然,我可以延长生命周期并使其长于remember_me选项的生命周期。但是,每次用户进行身份验证时,从用户设置重新读取区域设置将是一个更清晰的解决方案。

我假设认证是在每一个请求上完成的。通过登录表单(=交互式登录)提交的用户凭据或存储在remember_me cookie中的信息。这是不正确的?

在这种情况下,我希望每次请求都会触发remember_me事件。但事实似乎并非如此。

长话短说:

如何确保用户登录时使用用户设置中的区域设置?

1 个答案:

答案 0 :(得分:0)

根据我的经验,每次我们发出请求(如果基于会话的身份验证)symfony检查请求是否匹配任何活动会话(使用某些cookie作为会话标识符或类似的东西)。如果是,则触发onAuthenticationSuccess,否则您将被重定向到登录页面。提交登录表单后,如果用户凭据有效,您将通过身份验证并触发onSecurityInteractiveLogin

因此,如果凭据在每个请求中都有效,则onAuthenticationSuccess会触发,而onSecurityInteractiveLogin仅在成功登录时触发提交。 在任何情况下,经过成功验证后,您将在整个内核事件中转发到目标URL,从onKernelRequest事件开始。

所以,我认为问题可能是,当成功发生onAuthenticationSuccess时,您实际上会将用户语言填充到会话中,但在此之后触发onKernelRequest并使用此

$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));

如果这是问题,请考虑在onSecurityInteractiveLogin事件

中设置语言