【问题标题】:Preventing Update of LastUsed in MetadataBag for specific Controller防止更新特定控制器的 MetadataBag 中的 LastUsed
【发布时间】:2018-06-21 16:40:04
【问题描述】:

我为kernel.request 编写了一个事件监听器,让我能够在用户闲置超过一定时间时自动注销用户。
我用它来计算空闲时间:

$idle = time() - $this->session->getMetadataBag()->getLastUsed()

但我的页面中有一个定期的 Ajax 请求(用于页面中的通知计数),它们会不断更改 MetadataBagLastUsed 字段,因此永远不会达到空闲限制。
是否可以阻止特定的 Controller(那个 ajax 控制器)更新会话 LastUsed
如果是,如何?
如果不是,我还能做些什么来处理这个问题?

谢谢

【问题讨论】:

    标签: symfony session


    【解决方案1】:

    不知道怎么防止MetadataBaglastUsed更新,但是可以手动设置用户最后一次请求的时间,在session中使用。
    您可以创建如下所示的侦听器并使其侦听kernel.request 事件,然后在您的其他侦听器中,使用会话中的此侦听器而不是$this->session->getMetadataBag()->getLastUsed() 获取您存储的数据。

    public function listen(GetResponseEvent $event){
      // in your listeners main function
      $request = $event->getRequest();
      $route = $request->attributes->get('_route');
      if($route != 'your_ajax_check_route'){
        // update the session and etc.
        // retrieve what you store here in your other listener.
      }
    }
    

    【讨论】:

    • 整洁。您使用相同的侦听器来更新上次请求时间并检查是否已达到空闲限制。回答赞成。
    【解决方案2】:

    如果没有一些不必要的 Symfony 黑客攻击,您正在谈论的功能(防止更新会话 lastUsed)就无法完成,因为您可以为此简单地创建自己的逻辑。例如,您可以创建KernelRequest listener,它将更新所有请求的最后使用的会话变量,除了您将用于检查还剩多少时间的注销:

    public function onKernelRequest(GetResponseEvent $event): void
    {
        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
            return;
        }
        //$this->sessionMaxIdleTime is number from config parameter 
        //representing max idle time in seconds
        if ($this->sessionMaxIdleTime > 0) {
            $this->session->start();
            $time = time();
    
            $route = $event->getRequest()->attributes->get('_route');
            //for all routes but one - checking how much time is left
            if ('session_check' !== $route) {
                //manual set lastUsed time 
                $this->session->set('manualLastUsedTime', $time);
            }
            $idleTime = $time - $this->session->get('manualLastUsedTime');
            if ($idleTime > $this->sessionMaxIdleTime) {
                $this->session->invalidate();
                $this->session->getFlashBag()->set('info', 'Logged out due to inactivity.');
    
                if ($event->getRequest()->isXmlHttpRequest()) {
                    $event->setResponse(new Response('Logged out due to inactivity.', Response::HTTP_FORBIDDEN));
                } else {
                    $event->setResponse(new RedirectResponse($this->router->generate('login')));
                }
            }
        }
    

    然后您可以在某个控制器中简单地创建方法,该方法将被某些 ajax 函数用于检查还剩多少时间退出,例如:

    /**
     * @Route("/session/check", name="session_check", methods={"GET"})
     * @param Request $request
     * @param SessionInterface $session
     * @param int $sessionMaxIdleTime
     * @return JsonResponse
     */
    public function checkSecondsToExpire(Request $request, SessionInterface $session, $sessionMaxIdleTime = 0): JsonResponse
    {
        $idleTime = time() - $session->get('manualLastUsedTime');
        $secToExp = $sessionMaxIdleTime - $idleTime;
        return new JsonResponse(['secToExp' => $secToExp]);
    }
    

    最后一点是做一些检查机制。它可以像在基本模板中启动一些 JS 函数一样简单。参数为twig语法,来自config(与kernelRequest监听器中的sessionMaxIdleTime相同):

    <script>
        $(document).ready(function () {
            SessionIdler.start({{ session_max_idle_time }});
        });
    </script>
    

    SessionIdler.start 只是一个在特定时间间隔内运行其他函数的函数(在本例中,它将在配置 sessionmaxIdleTime 之前运行 1 分钟):

    function start(time) {
        checkSessionCounter = setInterval(checkSession, (time - 60) * 1000);
        isCheckSessionCounterRunning = true;
        // console.debug("checkSession will START in: " + (time - 60) + "s");
    }
    

    checkSession 函数向我们的session_check 路由发出 ajax 请求,并取决于结果,它显示模式与关于太长时间不活动的正确信息。模态在隐藏时可以有一个按钮或一个动作,这将向session_extend路由发出另一个请求(它什么都不做——它只需要被kernelRequest监听器捕获以覆盖manualLastUsedTime

    这三个部分共同创建了一种机制,用于通知用户长时间不活动,而不会对会话 metadataBag 产生任何影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2016-05-13
      • 1970-01-01
      • 2022-01-27
      相关资源
      最近更新 更多