I'm building an Ajax app in Symfony2 where a user logs in, and then from that point forward everything is handled by POST requests. After defining the session lifetime to 5 minutes in config.yml
, I run into the problem of the user's session being invalidated after 5 minutes even though they're making POST requests. Each time a request is made, I'd like to reset the countdown before the session invalidates, but I'm not sure how to do this efficiently.
The method I'm currently thinking about is writing a listener for the kernel.request
event, checking if the request method is POST, and manipulating the session class. I haven't done this yet, but it doesn't seem like a clean solution, since the listener needs to fire everytime a request is made.
Here's my session config:
session:
default_locale: %locale%
auto_start: true
lifetime: 300
Any ideas? Is the solution plain PHP and not Symfony?
The lifetime of a session is it's maximum age. This is controlled via a cookie which has already been created and is not refreshed any longer from the server side (because the session is already established). You can just update this cookie manually and I think this will make it with symfony2.
The probably easiest is to regenerate the session id w/o destroying the session:
$this->get('session')->migrate();
This should trigger an update on the session cookie.
Probably related questions:
To expound upon what is all ready here, here is a complete working example registered as a kernel request listener. For this example, I've hard-coded the timeout to 1,200 seconds (20 minutes). You can pass in the amount of time from your parameters.yml file (which is what I did in production):
#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]
And the class:
#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);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With