我正在开发基于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
事件。但事实似乎并非如此。
长话短说:
如何确保用户登录时使用用户设置中的区域设置?
答案 0 :(得分:0)
根据我的经验,每次我们发出请求(如果基于会话的身份验证)symfony检查请求是否匹配任何活动会话(使用某些cookie作为会话标识符或类似的东西)。如果是,则触发onAuthenticationSuccess
,否则您将被重定向到登录页面。提交登录表单后,如果用户凭据有效,您将通过身份验证并触发onSecurityInteractiveLogin
。
因此,如果凭据在每个请求中都有效,则onAuthenticationSuccess
会触发,而onSecurityInteractiveLogin
仅在成功登录时触发提交。
在任何情况下,经过成功验证后,您将在整个内核事件中转发到目标URL,从onKernelRequest
事件开始。
所以,我认为问题可能是,当成功发生onAuthenticationSuccess
时,您实际上会将用户语言填充到会话中,但在此之后触发onKernelRequest
并使用此
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
如果这是问题,请考虑在onSecurityInteractiveLogin
事件