Как закрыть все сеансы для пользователя в 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);

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

Я добавил это своему пользователю класс:

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);
  }
}
Author: SebCar, 2016-04-23

4 answers

Себкар,

Это ошибка в самой безопасности Symfony: Объяснение ошибки, подлежащее пересмотру Первая ошибка

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

 2
Author: Rodrigo Santellan, 2016-04-26 03:46:25

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

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

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();
 6
Author: Federkun, 2016-04-24 00:45:22

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

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

Я не знаю, как настроен ваш пользователь, но вам может потребоваться реализовать Равнозначный интерфейс

 1
Author: Gustek, 2016-04-23 23:52:35

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

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

 0
Author: Letsrocks, 2017-03-19 15:32:00