Как закрыть все сеансы для пользователя в Symfony 2.7?

После того, как пользователь изменит свой пароль (в случае действия восстановления пароля), мне необходимо аннулировать все сеансы, подключенные к этому пользователю (он может быть зарегистрирован на нескольких браузерах / устройствах). Итак, после сохранения пользователя с новым паролем в базе данных мне нужно закрыть все сеансы, которые могут быть активны в разных браузерах / устройствах для этого пользователя. Я пробовал это:

$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); $this->get('security.token_storage')->setToken($token); 

Также попробовали:

 $this->get('security.token_storage')->getToken()->setAuthenticated(false); 

И это тоже:

 $this->get('security.token_storage')->setToken(null); 

Заранее спасибо!

Я добавил это в свой класс User:

 class User implements UserInterface, EquatableInterface, \Serializable{ // properties and other methods public function isEqualTo(UserInterface $user){ if ($user->getPassword() !== $this->getPassword()){ return false; } if ($user->getEmail() !== $this->getEmail()){ return false; } if ($user->getRoles() !== $this->getRoles()){ return false; } return true; } /** @see \Serializable::serialize() */ public function serialize() { return serialize(array( $this->id, $this->email, $this->password, // see section on salt below // $this->salt, )); } /** @see \Serializable::unserialize() */ public function unserialize($serialized) { list ( $this->id, $this->email, $this->password, // see section on salt below // $this->salt ) = unserialize($serialized); } } 

Solutions Collecting From Web of "Как закрыть все сеансы для пользователя в Symfony 2.7?"

Sebcar,

Это ошибка в Symfony Security: описание ошибки для обзора First Bug

Таким образом, вам придется переопределить абстрактный токен

Вам нужно отслеживать каждую сессию, открытую этим пользователем. Поскольку он может быть зарегистрирован на нескольких браузерах / устройствах, он может использовать разные сеансы.

Легкий способ сделать это – сохранить ссылку идентификатора сеанса вместе с идентификатором пользователя, чтобы вы могли получить все sessid пользователя.

 namespace AppBundle\Security; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\SecurityEvents; class LoginListener implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin', ); } public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { $user = $event->getAuthenticationToken()->getUser(); $session = $event->getRequest()->getSession(); /* * Save $user->getId() and $session->getId() somewhere * or update it if already exists. */ } } 

затем зарегистрируйте событие security.interactive_login которое будет запущено при каждом входе пользователя в систему. Затем вы можете зарегистрировать слушателя с помощью

 <service id="app_bundle.security.login_listener" class="AppBundle\Security\LoginListener.php"> <tag name="kernel.event_subscriber" /> </service> 

После этого, когда вы хотите отменить все сеансы для пользователя, все, что вам нужно сделать, это получить все идентификаторы сеанса этого пользователя, выполнить цикл и уничтожить их с помощью

 $session = new Session(); $session->setId($sessid); $session->start(); $session->invalidate(); 

Согласно документации по умолчанию, вы должны это уже произойти.

Например, если имя пользователя из 2 пользовательских объектов по какой-либо причине не соответствует, пользователь будет выведен из системы по соображениям безопасности. (…) Symfony также использует имя пользователя, соль и пароль, чтобы убедиться, что Пользователь не изменился между запросами

Я не знаю, как настроен ваш пользователь, но вам может потребоваться реализовать EquatableInterface

Попробуйте $session->clear();

Проверьте документацию