Symfony3 Обновить данные пользователей и аннулировать текущие сеансы

Как я понимаю, когда пользователь успешно входит в систему, 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? (Я думаю, это будет служба, которая запускается в событии выборки.)

или, может быть, я слишком усложняю вещи, и есть супер простое решение, которое я просто не понял =|


person Christopher Hoyos    schedule 29.04.2017    source источник
comment
вы уже видели этот stackoverflow.com/questions/27987089/ и этот stackoverflow.com/questions/28805856/?   -  person Matteo    schedule 29.04.2017
comment
Здравствуйте, я видел оба решения, и ни одно из них не сработало (почти уверен, что ясно дал понять в вопросе). После некоторого тестирования я думаю, что у него есть что-то делать с провайдером пользователя mongodb (?), Так как всякий раз, когда я проверяю isEqualTo() и меняю пароль, он возвращает false, но UserProvider все равно будет обновлять пользователя. Теперь я думаю, что я должен сделать свой собственный сервис для предоставления пользователю. Когда он вызывает refreshUser() и в случае, если isEqualTo() возвращает false, бросайте UnsupportedUserException, чтобы предотвратить принудительное завершение сеанса.   -  person Christopher Hoyos    schedule 30.04.2017