Я пытался реализовать 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
Все остальные пути заканчиваются бесконечной "схемой", где одна проблема следует за другой, и в конце концов вы оказываетесь в начальной точке.
С уважением.
Вероятно, вам нужно будет проверить свой токен, прежде чем вы получите пользователя, if (null !== $this->security->getToken() && $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED'))
, в зависимости от конечно, ваша версия symfony.
Как указано в этом выпуске https://github.com/symfony/symfony/issues/2753
Ваш слушатель также используется в другом URL-адресе, где ваш брандмауэр не настроен, что нормально, но в некоторых случаях в этом URL-адресе, если токен не существует, это означает, что пользователь, вероятно, не подключен. Поэтому предыдущая проверка должна это сделать.
security.yml
?