I have read dozens of solutions to this and tried almost every one of them, but my sessions times out quickly anyway. I'm using a Debian installation and have set max variable in /usr/lib/php5/maxlifetime to 86400. I've also set session.gc_maxlifetime = 86400 in php.ini. I've made the session cookie valid for one hour and every time I reload the page I update it with another hour. I have tried setting ini_set("session.gc_maxlifetime", "86400"); in my front controller. However nothing helps. If I login to my site and wait about 20 minutes the next time I click a link on the page I will be logged out. The session cookie is still valid and the session file in /var/lib/php5 still exists. I just don't get it. I should also mention that I use Parallels PLESK on the system and it has made a lot of modifications to the standard Debian install, but I don't think that's the problem. Anyone?
It's entirely possible there's more than one .ini being loaded and where the one you made your session changes to is being overridden by one loaded later in the chain. Dump out a phpinfo() where your session validation/login code are and see what the session settings are. Part of the output will also be a list of the .ini files that were loaded.
Is it possible you have something a .htaccess conflicting with everything else? And are you sure you do not set this somewhere else in your code or some custom php.ini?
Everytime I have such problems I finally realise I forgot ONE place.
Does php -i | grep session.cookie_lifetime (at console) or phpinfo() (in script) verify your change to the cookie lifetime parameter?
If you use Firefox, try installing the Web Developer Toolbar and Firebug to inspect the cookies and network activity. This is a very useful combination for me when investigating issues where the hash value of a session cookie changes.
It's also possible that somewhere in your code or libraries you have a call to session_set_cookie_params() that's overloading your expected behavior. You can inspect cookies with either of the extensions above to verify their expiration.
I'm not sure if this will help, but make sure you're using both ob_start() & session_start();
ob_start();
session_start();
That's weird, a solution could be to implement a "Remember Me" feature with cookie. I know sessions can be very fickle, if you log-in on another comp, or the same comp but different browser, the cookie could be destroyed.
Also is the session really getting destroyed? Or is a new session being generated?
Related
I am using sessions in an attempt to implement persistent logins for my users in a web application. The back-end is php 7.2 and apache, provided through Namecheap shared hosting.
I am setting a session cookie on the client with a "cookie_lifetime" and "gc_maxlifetime" of 604,800 seconds (one week). The server calls session_start() with these parameters and checks a $_SESSION key called "user_id" to see if the session_start() call has started an existing session (if the key is defined, the user is "logged in"). It does this every time the page is loaded. Everything works fine until about 40 minutes of inactivity have gone by, then the next page refresh and attempt to call session_start() and access any $_SESSION keys returns undefined for everything, despite the session cookie still showing an "Expires" value several days in the future in DevTools.
My understanding was that "cookie_lifetime", "gc_maxlifetime", and the associated "Expires" header for setting the client-side cookie would preserve session information for at least as long as the time specified, but this interaction is demonstrating that regardless of what I put in those fields, the $_SESSION superglobal will not return anything meaningful beyond ~40 minutes of inactivity.
Am I not understanding this correctly, or is there perhaps something wrong from a server configuration standpoint that is beyond the scope of the client-server application code?
I didn't fully get to the bottom of why this was occurring. I did reach out to the Namecheap support staff, however, and they told me their sessions were not malfunctioning in the same way after ~40 minutes; they continued to see session values that had been set several hours previously when they tried to recreate the issue using the same code and configuration as I was using.
I dug into the server configuration and reviewed the output of a phpinfo() dump and determined that the Registered save handlers were set to files user. I can't find out what the user component of that reflects, and maybe that's where the issue lies, but I was able to resolve the issue by explicitly specifying the session.save_path parameter rather than relying on the default (which was no value in the phpinfo output).
The support staff had said that the default location was /home/[user]/tmp/ and their sessions were showing up there, but mine were not. After adding the explicit save_path to php.ini, my sessions began to appear there and the ~40 minute expiration stopped occurring.
I'll hold off on accepting this as the answer in case anyone else can provide more insight/understanding, but I wanted to at least chime in saying that I had found a solution to my problem. I'm not sure what was happening before, but I could not find my session files anywhere sensible in the directories of my shared host user account and I'm wondering if they were there at all. It's also very strange to me that it worked for the support staff but not for me or a friend that I had test it on his own computer.
I have one user reporting that they are being logged out at 6:45 pm est (around that time). My session expire time is 24 hours and they login about 8 hours earlier.
Just as a test I set sess_time_to_update to PHP_INT_MAX as their is a known bug that causes session logouts when it is rotating the session.
The only thing I can think of that would cause this is Firefox's ability to restore previous tabs. This actually restores the session cookie even after the browser is closed.
She said this also happens in Internet Explorer...I couldn't find a setting in IE 11 to persist session cookies after the browser closes.
Do you have any ideas what could be causing this or an idea of what to investigate?
EDIT: This happened to another client. It happens only some days and doesn't happen to users at a different location. Is there anything I can do to determine how this is happening?
Try testing it in a few different browsers and see if it's still happening.
If it is, maybe:
Check if there are any cron jobs running server side that could be killing session cookies on the server?
Use a tool like IECookiesView to see what cookies are there, when they're set to expire and if anything is changing?
If they keep getting logged out at similar times try working out anything that might be happening server or local side at that time. It's unlikely a restore tabs (with cookies) feature could be randomly running at the same time.
I remember seeing a feature in Firefox to clear all cookies on exit as well, are they rebooting around that time?
Hope I helped.
I'm not sure that you're setting the actual expiration period of sessions to PHP_INT_MAX. As stated in the manual sess_time_to_update config controls how often the session class will regenerate itself and create a new session ID. In other words it's how often the session details (such as last activity) are getting updated, not expired.
On the other hand there are a few configuration directives that have influence on unexpected session expirations of your case:
sess_expiration: The number of seconds you would like the session to last. The default value is 2 hours (7200 seconds). If you would like a non-expiring session set the value to zero: 0.
sess_expire_on_close: Whether to cause the session to expire automatically when the browser window is closed.
Make sure that these settings are set fine and then try to reproduce the situation on your own browser to minify the scope of the problem. If you still experience random logouts add a log_message() call to session library's sess_destroy() to keep track of user session destruction that may give you a clue about the destruction pattern.
If nothing, I think that would be user's browser or CCleaner-like apps on her machine wiping off the cookie. Instruct her to factory reset her browser settings or install a brand new browser.
The other thing worth noting is that some CI libraries such as IonAuth has their own related configs. If you're using IonAuth for authentication please have a look at user_expire and remember_users directives in the ion_auth.php config file.
Hope it helps.
After one day of extensive research on the internet, I still can't figure out this one.
What is happening is that PHPSESSID in the cookie isn't persisting from one page to another.
This is happening in computers under one internet connection in a specific place. I've tested several others machines located elsewhere and everything works fine. I've checked session_start, there's no problem with subdomains.
I hope someone can help me out.
Things to check:
Is the time (and time zone!) set correctly on those computers? If it's set incorrectly, they may be discarding session cookies prematurely (possibly even immediately).
Is any odd security or "privacy" software installed on the computers? If possible, check if the issue persists under another browser on those machines.
Are these computers behind any sort of web proxy? If so, it may be meddling with cookies.
To use cookie-based sessions, session_start() must be called before
outputing anything to the browser. - PHP Documentation
Also you may want to check that your php.ini is configured properly to store your session cookies. Either that or call session_set_cookie_params() every time the page is loaded before the session is started in order to properly configure the session cookie's folder, domain, duration, etc.
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().
After I verified with my own computer that this was happening in this place, I realised that when I typed some URLs, they got somehow changed in the middle, for example http://www.medicmanager.com.ar/cloud/santiago/charisma/js/jquery.cookie.js was changed into http://www.medicmanager.com.ar/cloud/santiago/charisma/js/jquery.ckiooe.js, which of course gave 404.
I changed the ISP connection to another, and it started working, so I called the ISP and they told me they've been with this problem for 2 days, changing URLs and messing up with cookies.
Thank you all for your answers, and I leave this here in case someone is in doubt. Yes, it can be your ISP, very strange.
Setting the cookie lifetime to 0 means it will expire straight away, try setting it to another value e.g. 2592000 - which is 30 days in seconds.
EDIT: I meant time() + 2592000
I've been trying to track down some annoying session issues since my webhost upgrade to PHP 5.3.3 awhile back. I've determined that if there is an active session, calling session_start() from a subdirectory kills the existing session. As an example, I start a session and a user logs in to domain.com/index.php then the user navigates to domain.com/members/ which fires start_session() ... the user's session is lost.
I've dug around for this and can't find anything similar. Is there a PHP configuration that would account for this behavior?
Calling session_start() multiple times with that version of PHP shouldn't cause any problems, however there are other possible causes.
One possible explanation is that the client's browser isn't sending the session id back to the server. You can test this out by comparing the session id that both pages produce. Assuming that you have a controlled environment where you can test this properly, you can use session_id() to get the session.
It might also be that the user is hitting a different webserver. Since (by default) PHP stores sessions to disk, there is no way for multiple servers to share the session information. If this is a shared host, it's probably quite unlikely this is the cause. You can test this out however by using phpinfo(). It should give you enough information to determine if it's the same server or not. For multi-server systems, I'd look at storing sessions in memcache or mysql.
if your sessions works all right within the same directory (it is unclear from your question), there is the only possible reason for such a behavior, a pretty obvious one: "directory" cookie parameter.
It seems it is set to somewhat unusual value, other than default "/" for the session cookie parameter.
You have to check it out.
Anyway, it is almost useless to try ANY session/cookie related problem without an HTTP interchange log.
You have to use some HTTP sniffer, like LiveHTTPHeaders Firefox addon to see what cookie header was sent by the server and which one was returned by client.
Otherwise it's all going to be shooting in the dark.
Okay, as it seems from your yonder comment, the session id remains the same, so, no HTTP issue can be a reason. The issue become a kinda tricky to spot.
Could you please post your test script here?
I've spent quite a long time searching, trying, testing for what looked like the same problem. As google kept sending me here, I think sharing the solution might help others (though I feel strange posting on a 2011 question):
Session variables set in /bar.php were not set in /foo/foobar.php.
It realised that the issue had nothing to do with folder/subfolder when I finally found out that the link in http://www.example.com/bar.php was pointing to http://example.com/foo/foobar.php (missing www).
Correcting the URL in the html link solved the problem. Having no time to dig deeper, what I can figure out is that (in my config) Apache makes no difference and serves pages indifferently with and without www, whereas PHP doesn't share the session between what it considers being two different domains, example.com and www.example.com.
Is there a PHP configuration that would account for this behavior?
Yes, if the storage for the session data differs between those calls, the $_SESSION content will differ as well. The storage can be configured, see http://php.net/manual/en/session.configuration.php for all configuration options you have with sessions.
Next to that if PHP is unable to read the session store, you will get an empty array as well.
I can't tell you if this is the issue with your problem, but probably it's helpful.
BTW, calling session_start() and than having an empty $_SESSION is commonly a sign that a new session has been created. You can verify this if you use cookies for your sessions and you output headers_listDocs:
echo '<pre>', var_dump(headers_list());
If it contains a new cookie for the session, the session has been created with this request.
Lots of good suggestions here. Thanks everyone. I spent a good chunk of the weekend digging into this and wasn't able to directly resolve it. I ended up demonstrating to my webhost that this problem happens on two of his hosted sites and doesn't happen in a default install of PHP. To work around the problem, I ended up moving all of my login and session logic into a single class.
Wanted to share another answer, found in this SO: Session variables not accessible in subdirectory answered by clayRay.
My answer was that I had a custom "php.ini" file saved in the root directory, and moving those directives into ini_set() calls solved it. You could also shove those over to .htaccess if your host allows.
I'm having problems with the PHP site I run at work where users are being logged out after a few minutes (the exact time varies, but it is frequent enough to be an issue), regardless of whether they have been actively using the site or not.
The difficulty is that I can't reproduce this problem, if I login as the same users using the same browser I don't get logged out, which suggests it is not a case of the site being completely broken. Unfortunately I don't have access to the user machines to run any traffic-sniffing software.
The things I have already checked are:
Asking users to try different browsers. This doesn't seem to solve the problem and isn't a long-term solution anyway as I can't dictate which browsers customers will use.
The server time is correct and in line with the user machines.
The user Apache runs as has permission to write to the session folder, and I can see the session files being created and their modification times being updated.
No output buffering functions are being used.
The problem is happening on a variety of pages which seem to have nothing in common (i.e. it's not that they all use AJAX, or update the database or some other reason).
Users only access their account from one machine, i.e. they don't do a bit of work on their laptop, switch to the desktop and then wonder why they've been logged out on their laptop (we don't allow multiple simultaneous logins for the same user).
The session settings in PHP are the Debian defaults, and haven't been changed in a .htaccess file or anywhere else. The main ones are:
session.cookie_lifetime 0
session.gc_divisor 100
session.gc_maxlifetime 1440
session.gc_probability 0
session.save_handler files
session.save_path /var/lib/php5
session.use_cookies On
Debian deletes sessions through a cron job instead of using PHP's garbage collector, which is why gc_probability is set to 0. The PHP version we're running is: PHP 5.2.6-1+lenny13 with Suhosin-Patch 0.9.6.2 (cli) (latest version in Lenny, we'll be upgrading to Squeeze soon but I don't think that is the cause of the problem).
We use Zend_Session to manage sessions, and an instance of Zend_Session_Namespace is created once on every page, thus automatically calling session_start(). Sessions are cleared by calling Zend_Session::destroy() on the logout page, so the only ways a user should be logged out are:
If they explicitly click the logout link (we log when this happens and it doesn't seem to be the case that browsing are pre-fetching the page and thus logging the user out).
If they leave the session inactive for more than 24 minutes, at which point Debian will probably delete their session (there's a cron job which runs every half hour deleting all sessions which have been unmodified for over 24 minutes).
If they close the browser, as their session cookie with an expiry time of 0 will be deleted.
The checks for seeing whether a user is logged in are:
They have a valid session (checked by seeing whether we can access $zsession->user_id).
There is a row in the sessions table which has a matching user ID and session ID, and this was last updated less than an hour ago. We delete this row on logout so that even if the session still exists on disk, no one can access that account without logging in.
Can anyone suggest other things I can try?
Edit: Some additional things I have tried based on comments left:
Setting session.cookie_domain: This seems to have very odd behaviour in PHP. If I do not set this variable and leave it as the default of '' (empty string), then a request for www.domain.com will produce a cookie of www.domain.com. However, if I set cookie_domain to 'www.domain.com', the domain for the cookie is '.www.domain.com' (notice leading dot, which means valid for everything below www.domain.com, e.g. subsite.www.domain.com).
Setting session.cookie_lifetime: PHP does not seem to update the expiry time on each request, so if I set cookie_lifetime to 3600 the cookie will expire one hour after the user first visits the site, even if they login and constantly use it.
Edit 2: Based on other things people have asked:
The site is hosted in a datacentre, on a separate VLAN. No one accessing the site is on the same network as the site.
There is no IP authentication used, nor is the IP address of the client used in any part of the session process (e.g. we don't attach the session to an IP address and block the user if their next request comes from a different IP).
Debian deletes sessions through a cron job instead of using PHP's garbage collector
That's very odd - and what is the code that runs in the cron job?
We delete this row on logout
I suggest you keep this for, say, 2 days after the session has expired / is deleted (but flag it as dead at the point where you currently delete it). Also, start logging the session id in your webserver logs.
In the end, the answer was to just scrap sessions and write my own very simple cookie code which differs from sessions in the following ways:
Stores a hash (bit like a session ID) in the database rather than in files.
Sets the cookie to expire in 3600 seconds from now (updated on each page) instead of 0 seconds (the latter seemed to cause problems for IE users, although I could never replicate it).
Only sends the cookie header when the user logs in or is logged in.
It's not an ideal situation as there's some reinventing the wheel going on, but my small solution seems to work where PHP sessions didn't, and having a working site is the most important thing.
I think you count change the value of
session.gc_maxlifetime
I also faced the same problem. I spent lots of time on it then i ask my web service provider and as he got the permission he changed that vale. Now it works fine.
Are there other php applications running on the same system (under different vhosts, for instance?)? Are they also saving sessions in /var/lib/php5?
If so, and one of those apps has a low session garbage-collection threshold, they will trash your app's session files.
I do a lot of ZF development, and if I'm using filesystem-based sessions, I stick them in application/data/session instead of the system default.
your session.gc_maxlifetime is set to 1440 ms which is only 1.44 seconds. shouldn't it be 1440000 ms = 24 minutes?
You could try setting session.use_only_cookies to a value of 1 and session.cookie_lifetime to a value of 1440 seconds.
is your site on different domains ? for example domain.com, www.domain.com, subdomain.domain.com ? if some pages are redirected to a different domain (www is considered a subdomain that is different) than the sessions will not work when the address changes
EDIT:
You must reproduce the problem. Ask your clients what kind of browser do they use, what action they do until they are logedout, are they viewing the same ip for the site as you do? (that is you are both in external networks or both in the same network with the site)
When you manage to find the problem, check the request/response headers when it the session works, and also when it does not work and then compare.
In the end I opted to send a Set-Cookie header on every page request, similar to what FlyBy suggested in one of the comments. The relevant code/logic now is (assuming session_start() has already been called):
$this->session_name = session_name();
$update_cookie = isset($_COOKIE[$this->session_name]); // Check if cookie already set, as PHP will send the first Set-Cookie when the session is started
$this->logged_in = $this->checkSession(); // Function which checks whether a valid (i.e. not timed-out) session row exists in the DB
if ($this->logged_in) {
$this->updateSession(); // Update the session row to the current time
if ($update_cookie) {
// Update the cookie expiry only if it existed before the login check
setcookie($this->session_name, $_COOKIE[$this->session_name], $this->time + 3600, '/');
}
}
I'm not sure why this worked, but I haven't had any further complaints and the number of logins has dropped drastically (no longer are there several logins in the logs for the same user within a few minutes of each other).
However, I will probably rewrite the code at some point to just use a database row and a cookie on the client, because the session functionality in PHP has so many variables that it's extremely difficult to work out what is causing the problem, and the session cookie handling is slightly different to how normal cookies are handled. In particular, you have to be careful with the setcookie function, because the default path for session cookies started by PHP is '/', but the default for setcookie is the current directory path, and these will not necessarily be the same.