如何在Symfony2中为另一个用户远程清除remember_me cookie?

时间:2016-05-29 08:51:16

标签: php symfony session cookies remember-me

所以我有这个基本的网络应用程序,只有一个用户(我)可以访问受保护的后台区域。我希望能够在其他设备(另一台计算机,我的手机等)上远程注销我的会话。

通过这种方式,我实现了session表:

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 ;

以及适当的处理程序:

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;
    }
}

这在处理登录和注销时很有效。记录在登录时正确插入,在注销时删除。现在,我可以执行以下操作来远程使会话无效:

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'));
}

但是,如果我在登录时选中“记住我”进行远程会话,这将无效

因此,我的问题是:是否可以为当前的其他用户清除“remember_me”cookie?

当然,我尝试$response->headers->clearCookie('remember_me');,但这结束了当前会话。

1 个答案:

答案 0 :(得分:1)

您无法清除另一个会话的Cookie,因为该会话的浏览器必须先发送请求,然后才能告诉它删除Cookie。这是一种不安全的方式来记录人们,因为任何有权访问cookie的人都可以手动重新添加它并重用会话。

实现此目的的正确方法是使用PdoSessionHandler将会话实际存储在SQL数据库中,然后如果要远程登录用户,则只需删除数据库中的会话即可。