2011-12-23 13 views
6

Estoy construyendo una aplicación Symfony2 Ajax en el que un usuario inicia una sesión, y luego desde ese punto hacia adelante todo lo que está en manos de las peticiones POST. Después de definir la duración de la sesión de 5 minutos en config.yml, me encuentro con el problema de la sesión del usuario ser invalidada después de 5 minutos a pesar de que estamos haciendo las peticiones POST. Cada vez que se hace una petición, me gustaría restablecer la cuenta atrás antes de que invalida la sesión, pero no estoy seguro de cómo hacer esto de manera eficiente.¿Cómo puedo actualizar la sesión durante una solicitud POST?

El método en el que estoy pensando actualmente es escribir un oyente para el evento kernel.request, comprobar si el método de solicitud es POST y manipular la clase de sesión. No he hecho esto todavía, pero no parece ser una solución limpia, ya que el oyente tiene que disparar cada vez que se hace una petición.

Aquí está mi sesión de configuración:

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

¿Alguna idea? ¿La solución es simple PHP y no Symfony?

+0

son las peticiones Ajax que se realizan a la misma nombre de dominio y aplicación Symfony como el que originalmente estableció la cookie de sesión? – RobNY

+0

Sí, mismo dominio, misma aplicación. –

+0

Agregue su configuración de sesión yml a la pregunta. – hakre

Respuesta

9

vida útil de una sesión es su edad máxima. Esto se controla a través de una cookie que ya se ha creado y ya no se actualiza desde el servidor (porque la sesión ya está establecida). Puede actualizar esta cookie manualmente y creo que esto lo hará con Symfony2.

El probablemente más fácil es regenerar el id de sesión w/o la destrucción de la sesión:

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

Esto debería desencadenar una actualización de la cookie de sesión.

preguntas relacionadas: Probablemente

+0

Esto funciona muy bien. Terminé usando un oyente en 'kernerl.request' después de todo. –

1

Para exponer sobre lo que está todo listo aquí, aquí es un ejemplo de trabajo completa registrada como una solicitud del núcleo oyente. Para este ejemplo, he codificado el tiempo de espera en 1.200 segundos (20 minutos). Puede pasar en la cantidad de tiempo de su archivo parameters.yml (que es lo que hice en la producción):

#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] 

Y la clase:

#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); 
     } 
    } 
} 
Cuestiones relacionadas