12

Is session_start() supposed to extend the life of the session ID cookie by the session.gc_maxlifetime variable?

My session.gc_maxlifetime is 24 minutes, and each session is only living 24 minutes regardless of additional activity on the site. I get my session, refresh the page, and the expiration time does not change. This results in a logout after 24 minutes of login, no matter what. Is there something wrong with my configuration?

Kirk Ouimet
  • 27,280
  • 43
  • 127
  • 177
  • I had the same problem as you did where the session SHOULD be extended as long as there is activity, and after doing many local tests I found simply adding session_regenerate_id() to be the best way for myself. – Scott Yang Mar 26 '13 at 00:29

3 Answers3

9

I had problem with this too. I was thinking that each

session_set_cookie_params($sessionTime, '/', $domain);
session_start();

causes that expiration time for cookie PHPSESSID is extended. But really cookie PHPSESSID is set by session_start() only first time in session when new session id is generated.

My goal was that session expiration time should regenerate each time a page was opened. I figured out that session can expire because of two reasons:

  1. Cookie PHPSESSID expires, and its expiration time isn't regenerated by session_start(), so session will always expire because of cookie with expiration time.
  2. No activity of user will cause that session will expire on server side. It is set by ini_set('session.gc_maxlifetime', $sessionTime).

Solution in this case is when you won't set expiration time for cookie, but session.gc_maxlifetime is still set:

function my_session_start($maxtime = 300)
{
    ini_set('session.gc_maxlifetime', $maxtime);
    session_set_cookie_params(0, '/', "." . $domain);
    session_start();
}

Most important is 0 in session_set_cookie_params(0, '/', "." . $domain) then cookie won't expire and there is no need to extend its expiration time. This cookie will be removed when browser is closed. Then we are limited only by time which expires on server side.

I had also problems with that I couldn't extend PHP session time by jQuery Ajax PINGs because of that I had set expiration time for PHPSESSID in cookie. 0 resolves all problems with not expected ends of sessions. Sorry for my English. Good luck.

8

I've noticed this behavior in PHP and tried every configuration on PHP but no luck so far.

My sessions were dying on exact time from first session_start(), lookig at cookie lifetime, it was not renewing its expiry time.

My application already has an important client count, about 60 connections per second, so the GC was hit every 1.5s (i guess).

My solution for cookie time not extending was something like this (It may seem not to elegant, but worked for me).

function my_session_start($maxtime = 300){
    // $maxtime = 300 for 5 minutes
    session_start( [ 'gc_maxlifetime' => $maxtime ] );
    $_sess_name = session_name();
    $_sess_id = session_id();
    setcookie( $_sess_name, $_sess_id, time() + $maxtime, '/' );
}

It's my particular solution, as the question says "session ID cookie". May not be the optimal, but indeed it works for me!

AMIB
  • 3,262
  • 3
  • 20
  • 20
  • 1
    I was just trying this out, and I had to change the last line to `setcookie($_sess_name, $_sess_id, time() + $maxtime, "/");` to get the cookie's path right. Without that fourth parameter, each folder winds up with its own cookie, and possibly its own session. (I didn't play with it long enough to tease out all the consequences.) – user1618143 Jul 11 '13 at 14:18
  • 1
    In fact i've hit your comment issue, regarding the path on Cookie, i'll update my answer, thanks!! – Frederic Yesid Peña Sánchez Jul 15 '13 at 17:50
  • @user1618143 the fourth parameter `"/"` was needed in my case too, PHP v5.6.40-13. – Arya Nov 07 '19 at 19:03
  • edited the code: added [ 'gc_maxlifetime' => $maxtime ] in order to tune PHP Session Garbage Collector. It is the best solution and it is optimum as PHP manages cookie headers correctly – AMIB Jan 13 '22 at 16:24
3

I think this post will provide the solution you are looking for: Session timeouts in PHP: best practices

Basically, when session_start() is called, there is a 1% probability (by default) that the garbage collector will be run. When the garbage collector is run it scans for and deletes expired sessions. However, when you are the only user accessing the page (which you probably are, during development) or there are very few users, the garbage collector will only run when you access a page. This happens AFTER session_start() is called, effectively resetting the timer. Instead of trying to work around this, just implement your own session_start() function which enforces the timeout. Try the function that the @Glass Robot posted, in the link I gave you above.

Community
  • 1
  • 1
Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
  • 1
    So PHP doesn't automatically update the cookie on session_start()? I have to do that manually? – Kirk Ouimet Sep 24 '10 at 23:32
  • It does update the expiration timer, but this timer is reset when you access another page. Try the function @Glass Robot posted (see my post). – Chris Laplante Sep 24 '10 at 23:33
  • Is it a bad idea to just regenerate the session ID on every request? – Kirk Ouimet Sep 24 '10 at 23:41
  • This is actually a good idea but it won't help with this issue. When you regenerate the session ID, PHP automatically moves the session data into the new session. However, this will probably still reset the timer. I would recommend adding a block of code to each page that tracks the session expiration and manually closes the session if the session has expired. – Chris Laplante Sep 24 '10 at 23:46