Today, I wanted to kill all user sessions, that have not been accessed for at least two hours. Now, there’s two ways to go about this.
Set session variables in php.ini and let PHP do the job
PHP brings it’s own session cleaning mechanism that involves these three settings in the php.ini:
session.gc_maxlifetime = 1440
session.gc_probability = 1
session.gc_divisor = 100
That translates to:
- A session is dead after 1440 seconds (24 minutes) of inactivity
- The chance that the garbage collection will be started is 1 in …
- …100 session starts (user logins)
That’s neat, if that you have lots of user logins. I was working on an internal tool with only 50 registered users. The chance to kill the session of one inactive user if all other 49 users logged in right after the two hours mark where still less than 39%. (1-0.99^49) Not ideal. So, what’s the other option?
Most Debian/Ubuntu systems come with a cronjob that kills stale sessions for you. It doesn’t care for your fancy session settings. Well, it only cares for one fancy session setting
session.gc_maxlifetime is still the deadline for stale sessions.
Now, you could combine the two approaches, but since my symfony was already tripping over itself with complex permission problems, I decided to rely on just the cronjob. I set the session.gc_maxlifetime to 10 and the session.gc_probability to 0, logged into my system, waited for 10 seconds, manually started the cronjob-script and voila… I was still logged in.
No Mr Session, I expect you to die!
Why? Why did the session not expire? Why was it still there? Taunting me from within the session folder. What did I forget? I ran the crobjob-script again. Nothing. So I started to augment the script with some ‘printfs’ and read the output. It said: “24 minutes max session lifetime”. Wait. What? I looked at my active PHP version: 7.1. I looked into the ‘/etc/php/7.1/apache/php.ini’ AND the ‘/etc/php/7.1/cli/php.ini’. Both said: Max lifetime is 10 seconds. What went wrong?
What went wrong?
I still had my old PHP 7.0 ini-files. Although PHP 7.1 was active, the cronjob-script looked at ALL possible ini-files and searched for the HIGHEST max session lifetime. Once I also changed the inactive ini-files to 10 seconds, all stale sessions where gone.