Let's say there's a site/system with a logged in member area, and users are rarely, but very inconveniently logged out while working with the site/system.
It's doubtfully session expiring, since the user was not idle for very long. And even if they were idle, I added a periodic AJAX request, a so called heartbeat, which updates the sessions' access time, and modified time. I even added a touch($session_file) every time a user clicks something or a heartbeat is called. I tried regenerating session ID as well. Nothing helped.
And unfortunately, so far, I was not able to reproduce the problem locally, because it happens every so often, when there's more requests. Some php.ini parameters:
session.use_cookies = 1
session.use_only_cookies = 1
session.cookie_lifetime = 0
session.gc_probability = 1
session.gc_divisor = 1500
session.gc_maxlifetime = 10800
I presume you are using built in PHP file session storage? There are known race conditions problems with it.
I had similar issues with loosing session id's when there were concurrent requests from same session id. Since file was locked by first request all other concurrent connections were unable to access file and some of them generated new session id. Those situations were also very rare and it took me time to locate the problem. Since then I'm using memcached for session storage and those problems vanished.
Here's something I've used. It uses javascript to 'ping' the server on an interval of 10 minutes.
Since sessions and authentication is already handled via one super controller in your code, it should be easy to at least rule out session destruction.
Typically only the login page creates a session, so at this point you can (and should) add a known value inside, such as the session id.
The other pages (including your heartbeat) resume an existing session, so at this point you look for the above value; if it's missing, you can do a few more checks:
session_id()
? if not, session file was lost due to garbage collection.session.use_only_cookies
setting.The above set of checks should point you in the right direction.
All the provided answers have shown good insight to the question, but I just have to share the solution to my exact problem. I was finally able to reproduce the problem and fix it.
So the system contained two subsystems, let's say admin and client interfaces. The admin was unexpectedly logged out when they logged in as client in another tab and logged out the client interface while being logged in as admin. It was doing this because everything was written to one session with namespaces. What I did is remove the code that kept destroying the session on logout action, and replaced it with session namespace unsetting and replacing with guest session for that namespace that only has access to the login page.
It is hard for me to answer this without further information however are you sure this only happens when you have more traffic. What can be done:
Do you have any session checks that rely on the IP. If so it might be that you are actually using a proxy which gives a different IP once every so oftern (like Cloudflare) in which case you can use the
HTTP_CF_CONNECTING_IP
to get the actually constant IP.I have also noticed one more thing:
So the cookie will actually be destroyed when the browser closes. Is it possible the connection is lost because the user closes the tab (which in some browsers does actually clear the cookies)?
As others have suggested I would strongely say you move to a DB session. Using a central session store can help in stopping race conditions, it won't stop them completely but it does make it harder. Also if you really get that many session ids you might wanna look into using something other than the built in PHP session id, however the built in hash is extremely unique and has a very low chance of being duplicate so I don't think that's your problem.
Clarification Edit:
If you are using a different proxy to Cloudflare then you will, of course, need to get the HTTP header thart your proxy sets, using Cloudflare is an example.