SessionListener (EventListener) для автоматического выхода из системы (Symfony)

1

Я пытался реализовать SessionListener, который должен выгнать пользователя в фоновом режиме после x минут бездействия. Это работает хорошо, но слушатель также вызывается, когда пользователь еще не вошел в систему - не должно быть такого.

Поэтому я попытался ввести TokenStorage в свой прослушиватель, но когда я пытаюсь проверить, существует ли пользователь в этом токене, я получаю сообщение об ошибке:

"Контекст безопасности не содержит токена аутентификации. Одна из возможных причин может заключаться в том, что для этого URL не установлен брандмауэр".

Поскольку я читаю сейчас в Интернете, это происходит потому, что Listener выполняется до того, как TokenStorage инициализируется в процессе "Symfony".

Как я могу обработать только следующий код в инструкции 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

Определение моего сервиса слушателя:

 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) Проверяйте Listener для этой переменной сеанса дополнительно 3 ) Установите Службу прослушивателя на приоритет> 8


Все остальные пути заканчиваются бесконечной "схемой", где одна проблема следует за другой, и в конце концов вы оказываетесь в начальной точке.

С уважением.

  • 0
    Вы можете опубликовать конфигурацию своего брандмауэра в security.yml ?
  • 0
    Обновил мой вопрос.
Теги:
security
session
session-timeout

1 ответ

0

Вероятно, вам нужно будет проверить свой токен, прежде чем вы получите пользователя, if (null !== $this->security->getToken() && $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED')), в зависимости от конечно, ваша версия symfony.

Как указано в этом выпуске https://github.com/symfony/symfony/issues/2753

Ваш слушатель также используется в другом URL-адресе, где ваш брандмауэр не настроен, что нормально, но в некоторых случаях в этом URL-адресе, если токен не существует, это означает, что пользователь, вероятно, не подключен. Поэтому предыдущая проверка должна это сделать.

  • 1
    эй, этот фрагмент не будет работать, потому что токен всегда будет возвращать ноль, поэтому пользователь никогда не будет выгнан из своего сеанса. Я обновил свой вопрос настройкой брандмауэра.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню