AWS Elastic Beanstalk PHP installation - session time out - php

I've observed that my PHP pages in the production environment session times out but unable to figure out what determines the duration of time out.
I use AWS ElasticBeanstalk to run the PHP code.
I'd like to find out
what is the session time set to and where is it set typically?
how I can programmatically control the time out from the PHP layer
Thanks in advance

If the session timeout is not explicitly set through the code, then you can check the default value set in the php.ini file for session.gc_maxlifetime which specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Garbage collection may occur during session start (depending on session.gc_probability and session.gc_divisor). Defaults to 1440 (24 minutes).
References:-
session.gc_maxlifetime
PHP - How to implement session lifetimes

Related

PHP Garbage Collector Keeps Removing My Sessions

The Problem:
I have a website that uses PHP sessions to allow users to log in. It works fine. But the session expires too soon that 1 minute of inactivity will log out the user.
My Environment:
Php version: 7.1
Server: NGINX
Framework: CakePHP 3.5
What I did so far?
I did every single solution on the StackOverflow or any search result I get. I extended my session timeout both in php.ini and CakePHP configurations.
The solution
After 2 or 3 days of research, I found the solution. In my php.ini I found a configuration named session.gc_probability and I put value 0 for that. Now my sessions never get expired except if the user logs out intentionally.
And now my current problem is, I don't want my session.gc_probability configuration to be zero as it will not collect any garbage (Not really sure about this. Please correct me if this information is wrong.). And this will cause the sessions to remain for month or years which a real GARBAGE for the server.
I got the idea of giving session.gc_probability zero value from here
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.
What is exactly wrong with my configurations? What causes the garbage collection to remove my sessions that soon? session.gc_probability was 1 and session.gc_divisor was 1000. I think a process with 1/1000 probability should not start every 1 or 2 minutes.
According to your follow-up comments your setting for Session.handler is php. The Sessions documentation explains:
The built-in configurations are:
php - Saves sessions with the standard settings in your php.ini file.
cake - Saves sessions as files inside tmp/sessions. This is a good option when on hosts that don’t allow you to write outside your
own home dir.
[…]
The default php.ini setting for session.save_path depends on your PHP distribution (and it can be changed anyway) but it normally involves a shared data storage for all PHP applications that do not opt out. That means that the app with the shortest session.gc_maxlifetime is likely to remove session data from other apps.
Switching to cake should address that.
A little follow-up about session.gc_probability and session.gc_divisor. Setting them too aggressively will cause frequent garbage collection. That may harm performance but it won't cause premature data expiration. On the other side, too loose values will still allow access to obsolete data.

Is session.gc_maxlifetime still based on last modified date?

According to this answer, the session.gc_maxlifetime is based (as of PHP 4.2.3) on the last modified date of the session:
Note: If you are using the default file-based session handler, your filesystem must keep track of access times (atime). Windows FAT does not so you will have to come up with another way to handle garbage collecting your session if you are stuck with a FAT filesystem or any other filesystem where atime tracking is not available. Since PHP 4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not available.
I can find nothing on the official documentation about that, the note seems to be disappeared, so is this still true?
The right answer is yes(PHP 5 - PHP 8), it based on last modified time.
And if php script read session variable, php runtime will update modified time.
The c souce is here (PHP 7.3 C Source):
No, session.gc_maxlifetime worksby time interval defined.
This value (default 1440 seconds) defines how long an unused PHP session will be kept alive. For example: A user logs in, browses through your application or web site, for hours, for days. No problem. As long as the time between his clicks never exceed 1440 seconds. It's a timeout value.
PHP's session garbage collector runs with a probability defined by session.gc_probability divided by session.gc_divisor. By default this is 1/100, which means that above timeout value is checked with a probability of 1 in 100.

Apache session works differently on the same server

The situation is we have a local server machine with Apache on it, and two projects on the same local server.
The problem is when we set up session.gc_maxlifetime = 10, for example, the server logs out on project N1 after 10 seconds with deleting the session file successfully, but on the other project N2, the session files are not deleted and the session is not logged out.
session.gc_probability and session.gc_divisor are both set up to 1.
What could be the reason of that?
Thanks.
It could be because of PHP garbage collector, which may or not remove sessions after desired period of time. See explanation:
http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime
session.gc_maxlifetime specifies the number of seconds after which
data will be seen as 'garbage' and potentially cleaned up. Garbage
collection may occur during session start (depending on
session.gc_probability and session.gc_divisor).
(Emphasis mine)

Using Xampp, php's session timeout doesn't work

I tried to change the value of session.gc_maxlifetime in php.ini to a small value so I could check if the session timeout was working or not, but the session never seems to expire. I also restarted apache to reload the php.ini.
Does anyone know what can be the cause ?
The directive is called session.gc_maxlifetime and the gc prefix provides a little hint on how it works: PHP includes a built-in garbage collection process that takes care of physically removing obsolete session data from disk. But that process is not launched on every PHP request because that'd be an unnecessary overhead (even a single HTML document can trigger the execution of some dozen PHP scripts). Instead, it's executed randomly. That's controlled by the two other directives that start with "gc_":
session.gc_probability
session.gc_divisor
Quoting from the manual:
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.
All this means that you cannot really know whether session.gc_maxlifetime is being honoured until the process runs. And if you're testing it in your local development box the process will run very few times (unlike your live server where there're thousand hits per minute).
A quick way to force it is to make gc_probability equal to gc_divisor so probability becomes 1.

How is PHP $_SESSION timed out?

What exactly happened?
I don't know the undergoing so I can't understand how session_set_save_handler() actually works.
Session timeout is declared in php.ini
If you can edit the php.ini, change:
session.gc_maxlifetime 72000
If you cannot edit the php.ini, put this in your .htaccess file:
php_value session.gc_maxlifetime 72000
That should allow the session to "live" for at least 20 hours (72,000 seconds), even without any activity.
If that doesn't work, and you're on a shared host, it could be that the host empties the session directory on a periodic basis. Do your sessions all die after a pre-determined amount of time? (i.e. 10 mins?) If that's the case, you could move your sessions into the database using a custom session handler.
Most people would think session.gc_maxlifetime defines the session’s lifetime.
But that’s not quite correct. session.gc_maxlifetime is only the lifetime after that the garbage collector of PHP’s session implementation assumes the session to be expired. But the garbage collector is only called with a chance of 1% (default settings). So it’s very probable that the session might be used though it is already expired.
The best would be if you implement a session timeout mechanism on your own and register it with session_set_save_handler. It should test if the current session is still valid and invalidate it immediately if it’s expired.
See my response to How do I expire a PHP session after 30 minutes? for further details.

Categories