【发布时间】:2015-05-27 04:16:11
【问题描述】:
我试图实现一个 SessionListener,它应该在 x 分钟不活动后在后台踢出用户。 这很好用,但是当用户甚至没有登录时也会调用侦听器 - 不应该那样。
所以我尝试将 TokenStorage 注入到我的侦听器中,但是当我尝试检查此令牌中的用户是否确实存在时,我收到了错误消息:
"安全上下文不包含身份验证令牌。一种可能 原因可能是没有为此 URL 配置防火墙。”
正如我现在在互联网上看到的,这是因为在“Symfony 进程”中初始化 TokenStorage 之前执行了侦听器。
我现在如何才能在用户登录时只处理 if 语句中的以下代码?
public function onKernelRequest(GetResponseEvent $event)
{
if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
return;
}
$session = $event->getRequest()->getSession();
$session->start();
$metadataBag = $session->getMetadataBag();
$lastUsed = $metadataBag->getLastUsed();
if ($lastUsed === null) {
// the session was created just now
return;
}
// timediff ...
$timeDiff = ...
// How to check here in addition that the user is logged in ?
if($timeDiff > self::MINUTES)
{
$session->invalidate();
$kicked_msg = $this->translator->trans('account.user.sessionTimeout', array(), 'User');
$session->getFlashBag()->set('info_message', $kicked_msg);
}
}
Security.yml 防火墙配置:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
default_target_path: /
logout: true
anonymous: true
我的Service对监听器的定义:
library.verify_session.listener:
class: Library\UserBundle\EventListener\SessionListener
arguments: [@translator, @session, @security.token_storage, @security.authorization_checker]
tags:
- { name: kernel.event_listener, event: kernel.request, priority: 100, method: onKernelRequest }
scope: request
对我来说,问题似乎是最重要的。 Http Firewall Listener 的优先级为 8。
如果我将侦听器更改为优先级 7,则错误消失了,因为我的侦听器在防火墙侦听器之后执行,因此令牌存在。
我现在遇到的问题: 我不再被会话监听器注销,我看到了 flashbag,但它没有把我踢出去/清理会话......?为什么会这样?
解决方案:
我尝试了我能想象到的一切,我发现唯一完整的工作方式如下: 1)登录/认证后,设置一个像“logged”=> true的会话 2)另外检查该会话变量的监听器 3) 将监听服务设置为优先级 > 8
所有其他方式最终都会进入一个永无止境的“循环”,一个问题接踵而至,最后,你最终到达起点..
问候。
【问题讨论】:
-
你能把你的防火墙配置发到
security.yml吗? -
更新了我的问题。
标签: php security symfony session session-timeout