Как я понимаю, когда пользователь успешно входит в систему, Symfony сохранит копию User
документа/объекта либо в session.handler.native_file
, либо в провайдере БД, в зависимости от того, что настроено. При будущих запросах эта информация извлекается с идентификатором сеанса, хранящимся в файле cookie.
Моя проблема заключается в том, что всякий раз, когда пользователь обновляет свой пароль или имя пользователя (которое является их электронной почтой), ранее открытые сеансы на разных компьютерах или в браузерах не истекают или устанавливаются как недействительные.
Предполагается, что EquatableInterface
проверяет это, но на самом деле это не работает для меня. Когда я добавил следующую заглушку в класс User
:
#User.php
public function isEqualTo(UserInterface $user)
{
return false;
}
После обновления в браузере ничего не изменилось. Мой сеанс все еще был действителен, и проверка выборки User
с помощью dump($this->getUser())
дала мне обновленный в настоящее время User
, а не тот, который был сохранен в начале сеанса.
Я пытался использовать:
#security.yml
security:
always_authenticate_before_granting: true
Если бы это что-то сделало, но это действительно не сработало.
Используя Symfony Profiler, я вижу, что User
извлекается из базы данных каждый раз, когда я делаю запрос, и мне интересно, в этот момент UserProviderInterface
только что обновил пользователя в security.token_storage
вместо сначала проверьте изменения, чтобы завершить сеанс, если это необходимо.
Чтобы убедиться, что это происходит, я протестировал этот контроллер в двух разных браузерах:
#SomeController.php
public function indexAction()
{
$encoder = $this->get('security.password_encoder');
$user = $this->getUser();
$flag = $encoder->isPasswordValid($user, 'MY_NEW_PASSWORD');
dump($flag);
return [];
}
Я вошел в свое приложение в обоих браузерах, затем вышел из системы в браузере A. Я изменил пароль User
на 'MY_NEW_PASSWORD'
и просто обновил браузер B. Дамп был true
для нового пароля.
Если это так, я задаюсь вопросом: - Есть ли способ проверить базу данных перед предоставлением авторизации, когда User
был получен из security.token_storage
? (Я думаю, это будет служба, которая запускается в событии выборки.)
или, может быть, я слишком усложняю вещи, и есть супер простое решение, которое я просто не понял =|
isEqualTo()
и меняю пароль, он возвращает false, ноUserProvider
все равно будет обновлять пользователя. Теперь я думаю, что я должен сделать свой собственный сервис для предоставления пользователю. Когда он вызываетrefreshUser()
и в случае, еслиisEqualTo()
возвращает false, бросайтеUnsupportedUserException
, чтобы предотвратить принудительное завершение сеанса. - person Christopher Hoyos   schedule 30.04.2017