why is my PHP session expiring prematurely? - php

According to Chrome, my site's PHPSESSID cookie expiration is set to
Expires: Monday, November 26, 2012 2:46:39 PM
But the session expires after only a few hours. I am calling session_start() on each page. Reading solutions offered for similar questions, I tried setting
ini_set("session.cache_expire",300*24*60*60);
and
ini_set("session.gc_maxlifetime",100*24*60*60);
prior to session_start() but this did not solve the problem. (Their initial values are set to 180 and 1440 respectively.)
I'm on a shared server, and another suggestion was to change the default tmp directory so it's not root (where some garbage collection process might be deleting the cookies), so I did this with
$docroot = $_SERVER['DOCUMENT_ROOT'];
$tmpdir = "$docroot/tmpx";
session_save_path($tmpdir);
This does not solve the problem. (I also have the same problem in other browsers, not just Chrome.) What else might I be doing wrong?
UPDATE: I saved the file for my current session locally, then tried logging in a few hours later. While the PHPSESSID cookie in Chrome (ie, the cookie whose content is this session file's name) remains stored with a date 100 days in the future as expected, the actual session file on the server now contains no data. (It exists but it is 0 bytes instead of 192 bytes as previously.) So it looks like the session file is not getting deleted, but the contents are getting erased.

There are many possible reasons why session data is not being correctly handled. Most likely, the session is not being started on EVERY page that is loaded and uses the data. To fix this, make sure that session_start() is started on every single page that is called or redirected to. Also, if you make any changes to the session configuration (ex, ini_set()), make sure that that is applied either globally or on each any every page. To apply it globally, add
php_flag session.gc_maxlifetime <your value>
php_flag session.cache_expire <your value>
to your .htaccess file. Alternatively, you can add
ini_set("session.gc_maxlifetime", <value>);
ini_set("session.cache_expire", <value>);
directly before session_start() on every page that calls session_start().

Add this before session_start():
ini_set('session.use_cookies', 1);
ini_set('session.cookie_lifetime', 300*24*60*60);
File-based sessions may be broken on your system, for any number of reasons. Try using database-based sessions and see if that fixes things.

Related

Session cannot remain for a long time its automatically destroyed

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.

PHP Sessions & Cookies Getting Deleted?

On both Chrome & Firefox, this lasts for about an hour then the session cookie, and other cookies set by javascript disappear. I didn't even close the browser.
session_set_cookie_params(946080000); // 30 years
session_start();
$_SESSION['login']=true;
Gone. The session cookies are gone. I assume its not a browser thing because it disappears on both Chrome & Firefox. I didn't test on IE.
Is this normal behavior... I'm certain it is not being unset somewhere.
Sorry, I know I haven't given much info, but that's because there is not much info to give. It should work and it doesn't.
I think you are doing it wrong, if possible change php.ini to reflect the coockie duration you want to apply. Reading from php.net manual:
"Set cookie parameters defined in the php.ini file. The effect of this
function only lasts for the duration of the script. Thus, you need to
call session_set_cookie_params() for every request and before
session_start() is called.
This function updates the runtime ini values of the corresponding PHP
ini configuration keys which can be retrieved with the ini_get()."
This means you need to call it EVERYTIME in all your php file before you do a session_start(). A blog post that may have the solution: http://blog.centresource.com/2006/05/23/php-session-lifetime-an-adventure/
To change the value in PHP ini use following line:
php_value session.gc_maxlifetime "946080000"
Anyway its better to use a coockie, sessions aren't used for a long lifespan, rather use cookies instead.

session expire in website baker

Where can i set default session expire time in WebsiteBaker? It is by default destroying in 10MINS. I want to set more minutes/hours in development period and later want to change to default or x MINS.
Please help me waiting your reply.
Thanks
Websitebaker at least the current 2.8.2 Version and the upcomming 2.8.3 Version completely rely on server settings for session lifetime.
If you want different session settings you can add your settings to the config.php just before :
require_once(WB_PATH.'/framework/initialize.php');
This only works if your Server allows overrides by script.
Another option is to use a .htaccess file or change the server settings.
I don't know anything about website baker , so find where the session is started ( in you're project search all files for session_start(); ) , then before that line you can use :
//first parameter expects the number of seconds session cookie should be kept by the
//browser , in our case 10 seconds
session_set_cookie_params(10);
Or another option , at the root of you're website baker app ( index.php ) add that line and you should be ready to go .
Notes: if session cookie is destroied by the browser then php will issue another session id when you call session_start(); , so we don't realy care if the last session is still considered alive/active as in you're php script you will have an empty $_SESSION . Aditionaly you can set ini_set('session.gc-maxlifetime', 10); so that previous sessions will get deleted by the garbage collector in case you store the sessions on disk .
I assume you haven't changed it yourself (otherwise I guess you'd remember how you did it) and 10 minutes looks like a strange default value. I'd dare say you are hosting your app in a shared server, session data is being stored in the default shared location and there's some other app from another customer that's set a lower session life time. This problem happens because session data is not site-aware: when the PHP garbage collector removes session files that have not been accessed in 10 minutes it removes all the files in the directory; it has no way to know what web site they belong to.
I cannot tell you how to fix it in WebsiteBaker but in regular PHP you need to set a custom session directory within your account. Then (and only then) you'll have full control over your own session data:
session_save_path('/home/users/foo/sessions');
ini_set('session.gc_maxlifetime', 3*60*60); // 3 hours (or whatever you need)
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
session_start();

How to keep session alive for 1week without logout PHP, overwriting default server values?

How to keep session alive for 1week without logout PHP, overwriting default server values?
I need to do this in the PHP code.
You can set the session lifetime in your script by using the session_set_cookie_params -function call before the session is started. The first argument of the function call defines the session lifetime in seconds relative to the server time (so make sure the server clock is correct):
For example, to make a session last a week:
session_set_cookie_params(3600 * 24 * 7);
session_start();
This will override the setting in the php.ini -file.
Make sure to check up on the function documentation on the PHP -site: http://www.php.net/manual/en/function.session-set-cookie-params.php
Just wanted to add this even though it's an old thread for the sake of completeness for future googlers:
Beware if you are on a Debian system.
The /etc/cron.d/php5 script will still clean your /var/lib/php5/ directory containing your sessions based on the php.ini value session.gc_maxlifetime.
Alternative solution:
You say people are leaving open their browsers for days and complain that session expire. Simple solution: don't let session expire by sending an keep-alive request using eg. XMLHttpRequest every 10 minutes.

everlasting sessions in PHP

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 :)

Categories