After a user changes his password (in a recover password action), I need to invalidate all sessions connected to that user (he may be logged on multiple browsers/devices) . So, after I save the user with the new password in the database, I need to close all sessions that may be active in different browsers/devices for that user. I've tried this:
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
Also tried:
$this->get('security.token_storage')->getToken()->setAuthenticated(false);
And this too:
$this->get('security.token_storage')->setToken(null);
Thanks in advance!
I've added this to my User class:
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);
}
}
You need to track every session open by that user. Since he may be logged on multiple browsers/devices, he may uses different sessions.
An easy way to do it is to save a reference of the session id together with the user id, so that you can get all the sessid of an user.
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.
*/
}
}
then register a security.interactive_login
event that will be fired every time a user log in. You can then register the listener with
<service id="app_bundle.security.login_listener" class="AppBundle\Security\LoginListener.php">
<tag name="kernel.event_subscriber" />
</service>
After that, when you want revoke all the sessions for a user, all you need to do is retrieve all the session ids of that user, loop and destroy them with
$session = new Session();
$session->setId($sessid);
$session->start();
$session->invalidate();
Sebcar,
That is a bug in the Symfony Security itself: Bug explanation to be review First Bug
So you will have to override the Abstract Token
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With