Symfony2会话空闲通知

时间:2015-05-27 11:02:36

标签: symfony

我想实现会话空闲通知功能。如果用户在期间X没有进行任何活动,则应在对话框消息中提供问题Do you want to extend your session?

我的算法如下:

  1. 检查用户空闲时间过长的KernelEventListener(应该注销);
  2. 检查其用户的AJAX操作(/idle)应该被通知他很快就会退出;
  3. Javascript函数,它会重复调用ajax调用/idle动作&根据回应做一些行动;
  4. 到目前为止,除了检查用户是否在给定时间内闲置的部分(2)之外,我已经做了所有事情。

    Symfony2 Session使用 lastUsed()方法 MetadadataBag 。我在 KernelEventListener 中使用它。我的代码看起来像:

    <?php
    
    namespace AppBundle\Handler;
    
    use Symfony\Component\HttpKernel\HttpKernelInterface;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\HttpFoundation\Session\SessionInterface;
    use Symfony\Component\Routing\RouterInterface;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\Security\Core\SecurityContextInterface;
    
    class SessionIdleHandler
    {
    
        protected $session;
        protected $securityContext;
        protected $router;
        protected $maxIdleTime;
    
        public function __construct(SessionInterface $session, SecurityContextInterface $securityContext, RouterInterface $router, $maxIdleTime = 0)
        {
            $this->session = $session;
            $this->securityContext = $securityContext;
            $this->router = $router;
            $this->maxIdleTime = $maxIdleTime;
        }
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            if (!$event->isMasterRequest()) {
                return;
            }
    
            if ($this->maxIdleTime > 0) {
                $this->session->start();;
                $lapse = time() - $this->session->getMetadataBag()->getLastUsed();
    
                if ($lapse > $this->maxIdleTime) {
                    $this->securityContext->setToken(null);
                    $this->session->getFlashBag()->set('info', 'You have been logged out due to inactivity.');
    
                    $event->setResponse(new RedirectResponse($this->router->generate('user_login')));
                }
            }
        }
    }
    

    控制器操作:

    <?php
    
    namespace AppBundle\Controller;
    
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\JsonResponse;
    
    /**
     * Class DefaultController
     *
     * @package AppBundle\Controller
     */
    class DefaultController extends Controller
    {
        /**
         * 
         * checks whether User Session is IDLE. If so - notify else logout
         * 
         * @Route("/idle", name="idle")
         */
        public function autoLogoutAction()
        {
            $service = $this->get('session_idle.service');
            $idleTime = $this->container->getParameter('session_notify_idle_time');
    
            $response = new \stdClass();
            $response->expired = false;
    
            if ($service->hasExpired()) {
                $response->expired = true;
                $service->getSession()->getFlashBag()->set('info', 'You have been logged out due to inactivity.');
            } else if ($serive->needNotification()) {
                $response->expired = false;
                $response->message =  sprintf(
                    'Your session will expire in %d minutes', 
                    $service->getExpirationTime()
                );   
            }
    
            return JsonResponse($response);
        }
    }
    

    我面临的问题 - 在构建Session对象时的每个http请求上 - &gt; lastUsed 时间变化。

    是否可以在请求期间跳过lastUsed更新?

    也许可以在HttpKernelEvent中改变它的行为?还有其他解决方案吗?

0 个答案:

没有答案