【问题标题】:SessionListener (EventListener) to automatically Logout (Symfony)SessionListener (EventListener) 自动注销 (Symfony)
【发布时间】: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


【解决方案1】:

你可能需要在获得用户之前检查你的令牌,if (null !== $this->security->getToken() && $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')),当然这取决于你的 symfony 版本。

如本期所述https://github.com/symfony/symfony/issues/2753

您的侦听器还用于未配置防火墙的其他 url,这是正常的,但在某些情况下,如果令牌不存在,则表示用户可能未连接。所以之前的检查应该可以做到。

【讨论】:

  • 嘿,这个 sn-p 不起作用,因为令牌将始终返回 null,因此用户永远不会被踢出会话。我用我的防火墙配置更新了我的问题。
猜你喜欢
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多