如何在POST请求期间刷新会话?

时间:2011-12-23 00:35:18

标签: php session symfony

我正在Symfony2中构建一个用户登录的Ajax应用程序,然后从那时起,所有内容都由POST请求处理。在config.yml中将会话生存期定义为5分钟后,即使他们正在发出POST请求,我也会遇到5分钟后用户会话失效的问题。每次发出请求时,我都希望在会话无效之前重置倒计时,但我不确定如何有效地执行此操作。

我目前正在考虑的方法是为kernel.request事件编写一个监听器,检查请求方法是否为POST,并操纵会话类。我还没有这样做,但它似乎不是一个干净的解决方案,因为每次请求时都需要触发监听器。

这是我的会话配置:

session:  
    default_locale: %locale%  
    auto_start:     true  
    lifetime:       300  

有什么想法吗?解决方案是PHP而不是Symfony吗?

2 个答案:

答案 0 :(得分:9)

会话的生命周期是它的最大年龄。这是通过已经创建的cookie来控制的,并且不再从服务器端刷新(因为会话已经建立)。您可以手动更新此cookie,我认为这将使用symfony2。

最简单的方法是重新生成没有破坏会话的会话ID:

$this->get('session')->migrate();

这应该会触发会话cookie的更新。

可能相关的问题:

答案 1 :(得分:2)

为了阐述这里准备好的内容,这里是一个注册为内核请求监听器的完整工作示例。对于这个例子,我将超时硬编码为1,200秒(20分钟)。你可以传递来自parameters.yml文件的时间量(这是我在制作中所做的):

#src\My\AppBundle\Resources\config\services.yml
kernel_request.listener:
    class:  My\AppBundle\EventListener\KernelRequestListener
    tags:
        - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
    arguments: [@security.context, 1200]

上课:

#Place in your src\My\AppBundle\EventListener folder
namespace My\AppBundle\EventListener {

    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\HttpKernel\HttpKernel;
    use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
    use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
    use Symfony\Component\Security\Core\SecurityContextInterface;

    class KernelRequestListener {

    /** @var int */
    private $maxIdleTime;

    /** @var SecurityContextInterface */
    private $securityContext;

    function __construct(SecurityContextInterface $securityContext, $maxIdleTime) {
        $this->securityContext = $securityContext;
        $this->maxIdleTime = $maxIdleTime;
    }

    public function onKernelRequest(GetResponseEvent $event) {
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            // don't do anything if it's not the master request
            return;
        }

        $session = $event->getRequest()->getSession();
        $token = $this->securityContext->getToken();

        if ($session !== null && !($token instanceof AnonymousToken) && $token->isAuthenticated()) {
            $session->start();

            if ((time() - $session->getMetadataBag()->getLastUsed()) > $this->maxIdleTime) {
                throw new CredentialsExpiredException();
            }

            $session->migrate(false, $this->maxIdleTime);
        }
    }
}