I am trying to increase the SESSION time so that the users do not time out for 12 hours. This is a private site used only by employees and the timeout is annoying and it causes partially filled out data to be lost. According to what I read the following code should work:
ini_set('session.gc_maxlifetime',12*60*60);
ini_set('session.gc_probability',1);
ini_set('session.gc_divisor',1);
session_start();
but it has no effect. Any thoughts?
thanks
ini_set('session.gc_probability',1);
ini_set('session.gc_divisor',1);
These two are forcing PHP to run the session cleanup script for EVERY hit on your site. PHP's formula to run the gc is:
if (random() < (gc_probability / gc_divisor)) then
run_session_garbage_collector()
}
Right now you've got 1/1, so 100% chance of the garbage collector being run. While extending the timeout period is good, you also want to REDUCE the chance the collector runs at all. Otherwise you're forcing PHP to do a full scan of ALL session files and parse EACH one, for EVERY hit on your site, to find the odd one or two that might have expired.
Try setting the gc_probability to 0 to completely disable the garbage collector.
As well, be aware that changing the settings, as you are, within a script with ini_set() doesn't change the timeouts/defaults that OTHER scripts use. This script might have a longer timeout and changed probability, but if other scripts hav ethe default timeout (10 minutes or something), then they'll happily nuke any "stale" sessions.
The proper place to set session timeout/cleanup settings is at the php.ini level, so that it applies to all scripts on the site, not just this single script of yours.
You could try setting the session.gc_maxlifetime = 12*60*60 in your php.ini file.
Otherwise when your script ends the session.gc_maxlifetime variable will be reset each time.
from php.net/ini_set :
string ini_set ( string $varname , string $newvalue )
Sets the value of the given configuration option. The configuration option will keep this new value during the script's execution, and will be restored at the script's ending.
The session cookie might be expiring as well: session.cookie-lifetime
I'm not sure if by "private site" you mean its alone on a dedicated server, but if not:
If your session temp files are being stored in the same directory as other sites' tmp files, its possible that a lower session lifetime on another website is triggering garbage collection, which could delete your "private site's" session. Depends on server setup. Personally I've got a tmp folder for each client to avoid things like that.
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.
So your doing 1/1 - I'm not sure how that will actually function, but it could be odd behavior.
Hope this will help you. just copy and paste the bellow code in web.config file
<sessionState mode="InProc" stateNetworkTimeout="10" sqlCommandTimeout="30" cookieName="ASP.NET_SessionId" timeout="53200" regenerateExpiredSessionId="false">
<providers><clear/></providers>
</sessionState>
Related
I would like to manage the time that a session expire to be forever.
What do I have to change In the php configuration file so this change is permanent and I don't have to implement this in all the code I write?
After I make a change in the php file, do I need to restart apache for the changes to take effect?
It is not possible to store the session infinitely unless you do not use garbage collection in php. You could try to set the php ini settings and set the time to 10 years
// set the max life time, after this, session is seen as garbage
session.gc_maxlifetime=315360000
If you have cookies enabled:
session.use_cookies=1
#session.use_only_cookies=1
// set the cookie expiration as well
session.cookie_lifetime=315360000
To avoid Int overflow, do not use a value larger than 2,147,483,647 as this is the max an Int32 can hold.
I have an issue with session , my session is automatically destroyed after few minutes of inactivity ,i think its must be 24 minutes i.e. 1440 seconds.I want to session remain for a long time , i am using .user.ini file on the server and set session.gc_maxlifetime to 31557600 seconds and session.cookie_lifetime to 31557600 but nothing happened for me .Its still logout after 1440 seconds of inactivity .I have also attached session value of png image of phpinfo.
I hope your answer or any help will work for me.Thanks.
I'm not sure why your settings aren't working but I use the following on my scripts to overwrite the php.ini settings for session maxlifetime and session_save_path:
session_save_path('/pathto/writable/dir/on/your/account');
ini_set('session.gc_maxlifetime', 24*60*60); // 24 hours; change as necessary
session_start();
NOTE:
The session_save_path is important because the default path is /tmp and it may get deleted by the system administrator on a daily/week? basis.
In my experience, it's always been related to the php.ini file. In your case, the master and local values for session.gc_maxlifetime contradict. (gc stands for garbage collect) They don't have to agree with each other, since the local value is used for the running script. It just means there's two php.ini files on your system, located in different places, and the local php.ini file is overriding the master php.ini file settings. But, I'd be VERY suspicious of any files on your server which call session_start() which use the master php.ini file, or call ini_set(...) within the script itself. The way this works is that no matter what the value is set to, it only has meaning when it's time to do garbage collecting. And garbage collecting is done by session_start() but you can also trigger garbage collecting in other ways such as SessionHandler::gc or a cronjob as explained later in this post. When called, it checks the last modified time of the file on the server storing your session information. If the number of seconds that elapsed since then is greater than the current session.gc_maxlifetime value, it will destroy the session. Note this is the last modified time, not the last accessed time, so you'll want to change your session data frequently to prevent it from getting deleted if it's not changing. You should also be aware that there is a setting here, called session.lazy_write which, if enabled, and is enabled by default, WILL NOT update the last modified time of the session file in the event which the session data did not change. Thus you'll want to disable this if you want to minimize the chances of sessions being destroyed early for some unknown reason, or store a timestamp on the session so the data is always changing and you know when the session was last used, if old, you can manually call session_destroy(). To start another session, you can commit with session_write_close() then recall session_start(). Or, do all 3 at once with session_regenerate_id(true).
Nextly, if you initialize a session with session_start() with your intended settings, and continue to call session_start() with the intended settings with each request, awesome. But, once any file on your server calls session_start() with a different value for session.gc_maxlifetime, either from using the master php.ini value in your case, or the script calling ini_set(...) and ignoring the master value, it will check the file's last modified time against a different value and destroy your session despite your intended settings - is assuming it gets elected to be one of the 1 in 100 requests which have to garbage collect.
Another thing to be concerned with is session.cookie_lifetime. A value of 0 here turns the cookie into a browser session cookie. This means if the user closes their browser, then the session cookie will be deleted by the browser. Your master value is using 0. But your local value is using 31557600 (the average seconds in a year). So you should be fine here. But keep your eyes open if any scripts on your server override this value, use a value of 0, or use the master php.ini file.
You should also be aware of the default 1% garbage collecting CHANCE that a session will be destroyed as defined by session.gc_probability and session.gc_divisor which default to 1 and 100 respectively. Garbage collecting is done when start_session() is called, if, and only if, the request "randomly" gets picked to be the request to manage the Garbage Collecting. This means that even if the number of defined seconds for a session elapsed for it to expire, start_session() STILL won't garbage collect even for this expired session. Rather, most users will notice their sessions expire exactly to schedule due to the cookie the browser keeps track of having its timestamp expire. But the session isn't enforced until PHP garbage collects as per the garbage collection change when start_session() is called. If you want sessions to be wiped clean when they've expired, and start a new one, you should use session_regenerate_id(true). The true here means trash the $_SESSION data tied to the previous session and toss them a different session id as though their session expired.
You should also be aware that some systems, such as debian-based systems, have a cronjob which runs every 30 minutes to garbage collect based on the master php.ini configuration information.
See the comment here by Christopher Kramer: http://php.net/manual/en/session.configuration.php
I cannot verify if the above information about debian systems is true, but I've considered garbage collecting with a cronjob before to speed up users' requests so no one user gets stuck having to wait for their request to go through due to the maintenance which a cronjob could be handling.
In terms of solutions here:
One solution here is to adjust the master php.ini value, if you have access to it, then search your server for any PHP files which might be calling ini_set to see if there's any files conflicting with your settings to make sure they're not causing the unexpected behavior.
Another solution would be to limit such conflicts the script might be encountering by: (1.) renaming the session.name to something other than PHPSESSID. And/or (2.) changing the session.save_path path. Either of these by itself would suffice and avoid script conflicts.
A temporary fix might be to do something like change your session.gc_probability to 0 so the session garbage collecting NEVER happens. Or make it a much smaller chance by using something like session.gc_probability=1 and session.gc_divisor=100000. Then setup a cronjob to call SessionHandler::gc
See http://php.net/manual/en/session.configuration.php for more session config information.
Lastly I'd like to point you to this post which suggests good practices to prevent session hijacking, and for the most-part is the post I referenced when putting this post together: https://stackoverflow.com/a/1270960/466314
Note that it uses an approach to sessions which makes sure sessions expire on time, and not later (although browsers do a good job of this already with cookie garbage collecting). And it also makes changes to sessions, keeping track of the session last used time, so the session data is always changing to avoid the issue with session.lazy_write.
This concludes my suggestions. If you can narrow down the issue, try searching stackoverflow or asking a new question.
As stated here :
The best solution is to implement a session timeout of 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 also changes the session
file's modification date so that the session is not removed by the
garbage collector prematurely.
I have an intranet site that has to perform complex and lengthy MySQL operations, and I have to find a way to prevent a PHP Session timeout from happening while this is going on.
A PHP page has all the form data that the user can fill out. When the user hits the submit button, an Ajax call goes out with that data, and the Ajax call waits until the operation is completed and then notifies the user of the result. I have to prevent the site from timing out while this call is going on.
My first thought was to use setInterval and run a second ajax call every 10 seconds to a page that only loads the session and refreshes some of the data in it, but during a first test I noticed that the second call and any further calls were not answered until the first one completed (I used PHP sleep(20) in my first call to simulate a long wait). My script started several new ajax calls (which I watched in Firebug), but they all waited until the first call was completed - there was no response from the server until then. I think the server simply ignores a second call from the same client until the first is done. I doubt Apache would stop accepting calls because PHP is waiting for sleep to finish...
During my research on this I haven't really found out yet what event is used to consider a Session timeout. One page claimed that just using Ajax to load a picture would extend the Session time, but that doesn't sound right to me since that doesn't involve PHP - besides, if the server doesn't accept a second connection, that won't work. Another page said it has to do with whenever the Session variable data is being written do, but again that also doesn't match my experience since I have plenty of pages that write during login but not after that.
So my question is two-fold:
Which exact events have to happen or not happen within a given timeout period for the Session to be considered "timed out"? I am guessing there are two timers involved here - the cookie timeout in the browser and the Session timeout in PHP, but these are just guesses, and I'd like to hear from the experts on this.
How can I keep that Session alive while the process is still going on? The process may take an hour or longer. The site is an intranet site and not accessible from outside the network, so security is not quite as big an issue, but I still want the regular Session timeout to work outside of this page.
OK, I feel the need to clarify here.
I am trying to find out what happens behind the scenes on the server whenever a PHP session timeout is involved.
For example: If I have a script that takes 1h to create a PDF file but the timeout is set to 30 minutes, will the timeout be triggered because the user/browser/mouse is not active, or will the timeout NOT be triggered because a script is still running?
What I would like to know is what EXACTLY is going on - what events take place (both user and server created) in prolonging a session before it times out?
You can tell me about PHP settings all day, and I still won't know what happens.
Let's start with the basics as far as I understand them:
A typical session may consist out of a session file on the server, a session id, and often a cookie in the client browser that holds the session id and a timestamp.
I'm assuming that the session file on the server or some index of session files also includes a timestamp.
Which events cause these timestamps to be updated, and which of these timestamps is being used to determine that the session has timed out or not? I could see the server testing the cookie's expiration date to determine if the session should timeout or not, but it's probably safer to rely on the server information.
This is the type of information I'm looking for here.
Maybe I should close the original question and write a new one with this information - I'm open to suggestions here. When I wrote the original post, I just needed an answer for my project, but I realized that I will never fully understand the process until I know the workings in the background.
First, you have to know that while the user is active (browsing your Intranet by classic Link, or by ajax, because apache server can not make a distinguish) your sessions still alive.
If user become inactive after a period of time, or disconnect from your Intranet, so the minimum of time that the session will be destroyed will be tha value of the parameter that was set in php.ini :
session.gc_maxlifetime= TIME_IN_SECONDS
To configure properly the session time out you have to configure these 3 parameters :
; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.
; Default Value: 1
; Development Value: 1
; Production Value: 1
; http://php.net/session.gc-probability
session.gc_probability=PROBA_CHANGEME
; Defines the probability that the 'garbage collection' process is started on every
; session initialization. The probability is calculated by using the following equation:
; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
; session.gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request. Increasing this value to 1000 will give you
; a 0.1% chance the gc will run on any give request. For high volume production servers,
; this is a more efficient approach.
; Default Value: 100
; Development Value: 1000
; Production Value: 1000
; http://php.net/session.gc-divisor
session.gc_divisor=DIVISOR_CHANGEME
; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; http://php.net/session.gc-maxlifetime
session.gc_maxlifetime= MAX_LIFE_TIME_CHANGEME
I'm setting up a website, and I'd rather not put cookies on people's computers. Is it bad practice - or worse- insanely insecure to extend the sessions max timeout to a day or two days?
session_regenerate_id();
$profileid = $userdata['userid'];
$profile = $userdata['username'];
//Set session
$_SESSION['profileid'] = $profileid;
//Put name in session
$_SESSION['profile'] = $profile;
$_SESSION['loggedin'] = true;
Edit: Added code.
Edit: the php.ini line that I would modify is:
session.gc_maxlifetime = 1440
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).
This value (default 1440 seconds or [24 Minutes]) 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.
So increasing this value will most likely not have much effect on your script unless you expect your users not to click around your site. Like in the case of a logged in user watching a long video and then after watching find themselves logged out afterwards. If this is the case perhaps you should use a some javascript to poll the server every 20mins to keep the session open.
I don't think there's anything particularly insecure about it, as long as your code in general is secure.
However
a) The user will lose their data if they close the browser - which they might do for any reason. If you need to ensure that data is kept around for a longer period, between sessions, unless the user specifically opts out, use cookies. Otherwise, it seems kind of counter-productive to insist on no-cookies. To clarify, I think what I mean is, if the standard session lifetime isn't long enough, then you probably shouldn't be using $_SESSION to store the data. By it's nature, $_SESSION is ephemeral and can only be used for fairly ephemeral things.
b) Unless you're really going an extra mile to prevent all cookies, the PHP Session id will be set using a cookie anyway, so are you really doing your users any favours?
Is it possible to configure PHP sessions to never expire? I currently have the default 24 minutes set in php.ini - I could whack this up to a couple of weeks or something like that but I was wondering if I can set them to infinite lifetime?
I want to achieve a similar effect to Stackoverflow's: I never have to log in here. Is this achieved on SO with a never-expiring session or some other means?
Also, as a secondary question: How do the expired session files get cleaned up? If someone creates a session and never returns, which process is cleaning up their expired file?
Normally, what appears to be an everlasting session is two things: a session, which expires pretty soon, and a very long-life cookie containing an auto-login token.
There's a great series of responses on sessions and logging-in contained in this StackOverflow question: The Definitive Guide To Website Authentication
Regarding your question about when sessions are cleaned up, there are several php.ini settings for controlling when the garbage collection for sessions is triggered.
Since PHP both allows and encourages you to create your own session data storage handlers, there is no single correct answer to this question.
Answer to secondary question
Session file cleanup is controlled by the following 3 php.ini settings:
session.gc_probability (default value 1)
session.gc_divisor (default value 100)
session.gc_maxlifetime (specified the age after which the session is considered as garbage)
First 2 settings specify the probability of the garbage collection process being started at session start (before or at the very beginning of your script execution, depending on how you have set things up)
In default configuration there is a 1% probability then that this happens. If it does, then files that are older than maxlifetime are cleaned.
As for your first question - why not write a custom session handler, that stores sessions inside the database (if you have one). That way you can see and control the sessions right from inside the database. Handy :)