Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Sessions never expire

Last night I logged in and the following morning I was still logged in, even if I quit my browser. I want the session to expire after a few hours and I thought that it would work with "session.gc_maxlifetime" set to "1440" and "session.cache_expire" set to "180"

Here is what I could find from PHP.ini

Session Support                 enabled
Registered save handlers        files user
Registered serializer handlers  php php_binary wddx


session.auto_start        Off
session.bug_compat_42     Off
session.bug_compat_warn   Off
session.cache_expire      180
session.cache_limiter     nocache
session.cookie_domain     no value
session.cookie_httponly   Off
session.cookie_lifetime   0
session.cookie_path       /
session.cookie_secure     Off
session.entropy_file      no value
session.entropy_length    0
session.gc_divisor        1000
session.gc_maxlifetime    1440
session.gc_probability    0
session.hash_bits_per_character  5
session.hash_function     0
session.name              PHPSESSID
session.referer_check     no value
session.save_handler      files
session.save_path         /var/lib/php5
session.serialize_handler php
session.use_cookies       On
session.use_only_cookies  On
session.use_trans_sid     0

On our old server we used the same settings and the sessions worked. The only difference from the old one is the "session.save_handler" that is set to "memcache" on the old server. Also "session.save_path" is different.

like image 820
Toydor Avatar asked Dec 25 '22 20:12

Toydor


2 Answers

Relying on other things and hope them to work is not my thing. :D I think that the best solution would be to implement a session timeout on your own. Use a simple time stamp that denotes the time of the last activity (i.e. request) and update it with every request:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

Updating the session data with every request does also change the session file’s modification date so that the session is not removed by the garbage collector prematurely.

~Foorack

like image 162
Max Avatar answered Dec 28 '22 10:12

Max


It may help to change gc_probablity to something other than 0.

From the manual for gc_divisor:

session.gc_divisor coupled with session.gc_probability defines the probability that the gc (garbage collection) process is started on every session initialization. The probability is calculated by using gc_probability/gc_divisor, e.g. 1/100 means there is a 1% chance that the GC process starts on each request. session.gc_divisor defaults to 100.

If I'm reading from this right, with gc_probability being 0, the garbage collector is never run, rendering gc_maxlifetime useless.

GC is an expensive process for file-based sessions, so it's not a good idea to run it on every request, [edit: so PHP has a built in randomization to run it periodically]

Addendum: For anything with real security implications, it's likely better to handle invalidating the session in your script, as Max's answer suggests. Also session.cache_expire sets the default expiration for session pages that are sent to the browser, and doesn't affect session storage at all.

like image 41
EPB Avatar answered Dec 28 '22 10:12

EPB