Session expires even if I'm working, session lifetime, Ajax and Symfony2
ajax, php, session, symfony
Solution
First, watch out your `gc_probability` and `gc_divisor`. If both are set to one, that means that the probability that the garbage collector (GC) process is started on every session initialization is `gc_probability / gc_divisor = 1/1 = 1` (100%).
You could leave it to the defaults or give it a higher number in order to reduce the chance of the GC being called.
For instance:
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
cookie_lifetime: 600 # Ten minutes
gc_probability: 1
gc_divisor: 10000
Also, if you're using a Virtual Machine, check the date of your server, the resulting session cookie will be stamped with an expiry time of `time() + cookie_lifetime` where the time is taken from the server.
It could be possible that, if the server had a bad date, the cookie would expire inmediately. Imagine: server date `2015-01-31`, your browser `2015-02-01`. Server sends cookie that expires on `2015-01-31` at 11pm, your browser receives a cookie with an expiration date that has already passed.
Problem
I have configured my application for close session on timeout if user do nothing during 10 minutes period. At `config.yml` I have this: ``` session: handler_id: ~ cookie_lifetime: 600 # 10 minutes gc_maxlifetime: 600 # 10 minutes gc_probability: 1 gc_divisor: 1 ``` I do a Ajax call every one minute to check if session will be close to expire or doesn't and this is what I check: ``` public function isLoggedInAction(Request $request) { $response = array(); $response['authenticated'] = FALSE; $status = 200; $securityContext = $this->container->get('security.context'); if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) { $response['authenticated'] = TRUE; } return new JsonResponse($response, $status ?: 200); } ``` For some unknow reason is not working and every 10 minutes session is closed whether I'm working with page or doesn't, why? I'm missing something? Edit 1 Tried new values, still not working: ``` session: handler_id: ~ cookie_lifetime: 1800 gc_maxlifetime: 600 gc_probability: 1 gc_divisor: 100 ``` While I was working on the page, performing Ajax calls and some other tasks the session was closed so is not working. The only value that apparently works for me til now is set `cookie_lifetime: 86400 #1 day` which is crazy to me! Edit 2 After @acontell suggestion for fix the VM time and date I'm trying with this new values (10 minutes takes too long so I've changed to 3): ``` session: handler_id: ~ cookie_lifetime: 1800 gc_maxlifetime: 180 # session will expire after 3 minutes of inactivity gc_probability: 1 gc_divisor: 100 ``` And also I fixed the date/time on the VM by enabling `ntpd` service and now date is just fine: ``` [root@webvm var]# date Sun Feb 1 18:35:17 VET 2015 ``` But after 5 minutes (function call was executed 5 times) session still alive. This is how I call the function `isLoggedInAction()` from Javascript side: ``` $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){ if( data.authenticated ){ var timer = window.setInterval(function(){ $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){ if( !data.authenticated ){ window.clearInterval(timer); $.growl({ message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.' }, { type: "danger", allow_dismiss: false, timer: 10000, animate: { enter: 'animated fadeInDown', exit: 'animated fadeOutUp' }, onHide: function(){ location.reload(); } }); } }).fail(function(){}); },60000); } }).fail(function(){}); ``` See the image below: Test 3 After say all was working fine I did the latest and definitive test: open the application and leave untouched during all the night (almost 8 hours) and surprise it never closes the session. As image below show see how many request the page does and see how session still alive, why? Ajax call is made every: 10.5 minutes ``` $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){ if( data.authenticated ){ var timer = window.setInterval(function(){ $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){ if( !data.authenticated ){ window.clearInterval(timer); $.growl({ message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.' }, { type: "danger", allow_dismiss: false, timer: 10000, animate: { enter: 'animated fadeInDown', exit: 'animated fadeOutUp' }, onHide: function(){ location.reload(); } }); } }).fail(function(){}); }, 210000); } }).fail(function(){}); ``` Settings say that session should expire passed: 10 minutes. ``` session: handler_id: ~ cookie_lifetime: 630000 gc_maxlifetime: 630000 # session will expire after 10 minutes of inactivity gc_probability: 1 gc_divisor: 100 ``` Time at server is fine: ``` [root@webvm sencamer.dev]# date Mon Feb 2 07:26:53 VET 2015 ``` What else should I check? Test 5 Ok, I'm still doing test because this has not a good behavior. So, this is what I've do for this test: - Open the application and start working on it - At some moment stop working and leave the the application made the Ajax call to check whether session still alive or not. (session still alive see image below) - After that first call I continue working on the application as image 2 shows but surprise session ends and the application gets close. Why? What is causing that behavior? Is that right based on my parameters? This image shows the first and only call to the function After the call was made I continue working but session gets closed