使用remember_me功能登录后,如何刷新/扩展remember_me cookie(到期)?

时间:2015-02-03 15:16:37

标签: php symfony

我正在使用Symfony 2.3 LTS。

我可以充分利用Symfony中的remember_me功能,包括设置它并在会话到期后重新登录。但是我的问题是,一旦用户使用remember_me功能重新登录,则不会刷新到期日。

换句话说,如果您将remember_me Cookie的“生命周期”设置为14天,那么无论用户访问该网站的时间长短,他们都需要使用完整的用户名/密码重新进行身份验证(14天之后。)我不想在没有访问的情况下将更长的cookie设置为14天。

我知道如何手动设置remember_me Cookie。我只需要知道将代码放在哪里。

我试过这些:

  1. This SO question没有做我想要的事情而且非常不同。

  2. security.yml配置中似乎没有任何设置(刷新到期日期。)

  3. 挂钩processAutoLoginCookie中的Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices方法,但由于无法访问响应(无法手动设置Cookie),因此无效。

  4. 聆听SecurityEvents::INTERACTIVE_LOGIN事件看起来不错,但InteractiveLoginEvent也无法访问响应。 Here's an example.

  5. 通过使用上述之一设置请求属性然后设置响应侦听器来检测,我可能会变得混乱,但我认为这太乱了。必须有更好的方法来做到这一点。

  6. 我可以使用上述其中一项来侦听请求,生成响应(例如重定向),设置cookie,执行重定向,但这又不够好。

2 个答案:

答案 0 :(得分:3)

我建议的方法:

  1. 设置kernel.response监听器
  2. SecurityContext传递给侦听器构造函数
  3. 检测已登录的用户
  4. 手动设置remember_me Cookie
  5. 设置会话var以防止将来的cookie集
  6. 您的新Cookie将在使用remember_me Cookie登录时用户加载的下一页上捎带。
  7. services.yml

    services:
        acme.response_listener:
            class: AcmeBundle\EventListener\ResponseListener
            arguments: ['@security.context']
            tags:
                - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
    

    ResponseListener

    namespace AcmeBundle\EventListener;
    
    use Symfony\Component\Security\Http\Event\FilterResponseEvent;
    use Symfony\Component\Security\Core\SecurityContext;
    use Symfony\Component\HttpFoundation\Cookie;
    
    class ResponseListener
    {
        /** @var \Symfony\Component\Security\Core\SecurityContext */
        private $securityContext;
    
        /**
         * Constructor
         * 
         * @param SecurityContext $securityContext
         */
        public function __construct(SecurityContext $securityContext)
        {
            $this->securityContext = $securityContext;
        }
    
        public function onKernelResponse(FilterResponseEvent $event)
        {
            $session = $event->getRequest()->getSession();
            if (
                $this->securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') // remember_me cookie used
                && !$session->get('cookie_extended') // cookie hasn't been extended
            ) {
                $response = $event->getResponse(); // get the Response object
                $cookie = new Cookie(...); // your cookie
                $response->headers->setCookie($cookie); // set that cookie!
                $session->set('cookie_extended', true); // prevent future cookie sets for the current session
            }
        }
    }
    

    我没有测试过这段代码,但它应该足以让你开始朝这个方向发展。

答案 1 :(得分:0)

到期时间戳和密码都是cookie值的哈希值的一部分,因此似乎只能在登录时设置记忆cookie,因为密码必须可用于扩展时间戳。

来自https://stackoverflow.com/a/9069098

  

如果您直接设置记忆cookie,则必须使用以下格式:

base64_encode(<classname>:base64_encode(<username>):<expiry-timestamp>:<hash>)
     

哈希将是:

sha256(<classname> . <username> . <expiry-timestamp> . <password> . <key>)