D4V1D
D4V1D

Reputation: 5849

How to remotely clear remember_me cookie for another user in Symfony2?

So I have this basic web-app with a protected back office area accessible by only one user (me). I wish to be able to remotely log off my sessions on other devices (another computer, my phone, etc).

In that way, I've implemented a session table:

CREATE TABLE IF NOT EXISTS `session` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `session_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `login_date` datetime NOT NULL,
  `user_agent` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `ip` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_D044D5D4844A19ED` (`session_token`),
  KEY `IDX_D044D5D4A76ED395` (`user_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=15 ;

along with proper handlers:

LoginListener

<?php

namespace AppBundle\Event\Listener;

// use ...

class LoginListener implements EventSubscriberInterface
{
    protected $em;

    function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public static function getSubscribedEvents()
    {
        return array(
            SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
        );
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();
        $currentSession = $event->getRequest()->getSession();


        $session = (new \AppBundle\Entity\Admin\Session)
            ->setUser($user)
            ->setSessionToken($currentSession->getId())
        ;

        $this->em->persist($session);
        $this->em->flush();
    }
}

LogoutListener

<?php

namespace AppBundle\Event\Listener;

// use ...

class LogoutListener implements LogoutSuccessHandlerInterface {

    private $tokenStorage;
    private $router;
    private $em;

    public function __construct(TokenStorage $tokenStorage, Router $router, EntityManager $em)
    {
        $this->tokenStorage = $tokenStorage;
        $this->router = $router;
        $this->em = $em;
    }

    public function onLogoutSuccess(Request $request)
    {
        $session = $this
            ->em
            ->getRepository('AppBundle:Admin\Session')
            ->findOneBySessionToken($request->getSession()->getId());

        $this->em->remove($session);
        $this->em->flush();

        $response = new RedirectResponse($this->router->generate('blog_home'));
        $response->headers->clearCookie('remember_me');
        $response->headers->clearCookie('session');
        $response->send();

        $request->getSession()->invalidate();

        return $response;
    }
}

This works well when handling login and logout. The record is properly inserted on login and removed on log out. Now, I can do the following to remotely invalidate session:

public function clearSessionsAction(Request $request)
{
    $session = new Session();
    session_id('<whatever remote session id found in session table>');
    $session->invalidate();

    return $this->redirect($this->generateUrl('blog_home'));
}

However, this won't work if I checked 'Remember me' on login for remote sessions.

Therefore, my question is: is it possible to clear 'remember_me' cookie for another user than the current one?

Of course, I tried to $response->headers->clearCookie('remember_me'); but this ends current session.

Upvotes: 1

Views: 910

Answers (1)

Chris
Chris

Reputation: 5886

You can't really clear a cookie for another session because the browser for that session has to send a request before you can tell it to delete the cookie. This is an insecure way of logging people out anyway because anyone with access to the cookie can just re-add it manually and reuse the session.

The correct way of implementing this is to use the PdoSessionHandler to actually store your sessions in an SQL database and then if you want to log a user out remotely you can just delete the session in the database.

Upvotes: 1

Related Questions