Sounds like a basic question, but after hours of research I still have nothing to solve the problem.
I'd like a simple thing: keep users logged in on my website for longer than 24 minutes.
My site runs on an apache server and shared hosting, I do not have access to edit the php.ini file.
Messing around with
(session.gc_maxlifetime)
did not work.
I'm looking for a cookie-based solution at this point - a cookie that is stored on the client side, and is deleted at logout.
So PHP would not destroy the session despite of inactivity if this cookie is present.
Is this possible?
(I'm running a site with long articles, so users may be considered 'inactive' by the server and be logged out when they click for the next article. That's what is happening now.)
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.
I am in the process of moving away from Apache in favor of nginx due to the lower resource consumption. I have set up an Ubuntu Server box with the LEMP stack installed. After moving all my applications over (3 CakePHP 2.0.5 apps, 1 Wordpress install), everything seems to be working perfectly except for one thing - Cake's cookies suddenly disappear when the browser is closed.
I have created a very simple test PHP page to test if cookies are working at all and they are in fact working, just not in Cake. Wordpress is also not having any troubles remembering me when I close my browser.
Using the Chrome developer tools, I have inspected to see if the cookie is being set at all, and it is as you can see below:
The expiry date is even set a month into the future as well, so I don't understand why they don't live past browser close. As soon as I fire my browser up and navigate to my app, the cookie is now gone:
One thing I did notice is that with my app running on Apache, the CAKEPHP cookie you see above above has the same value before and after close. However on the nginx server, that cookie has a different value everytime I close and re-open my browser.
I thought this might have to do with sessions, so I checked my session settings in core.php and it's set to let PHP do the session handling:
Configure::write('Session', array(
'defaults' => 'php'
));
I've checked my /tmp directory and session files are being created. I tried changing the session handler to cake so that Cake would store sessions in its app/tmp/sessions directory, and while the sessions would successfully get created in this directory my cookies are still lost on browser close.
Has anybody experienced this behavior between nginx and Cake before, or have any ideas as to why this might be happening?
The problem is related to encrypted cookies and the Suhosin patch. Apparently Suhosin ignores any mt_srand() and srand() calls you make and initializes the randomizer itself [see here]. Because Cake relies on these functions, it was interfering with my encrypted cookies. To fix it, I added these two lines to my php.ini file and rebooted the server (note that simply restarting nginx didn't work):
suhosin.srand.ignore = Off
suhosin.mt_srand.ignore = Off
Im having trouble figuring out a couple things regarding sessions, the browser, and Magento (or probably any shopping cart for that matter). I understand that by default 24 minutes of inactivity will close a session. I am also under the the understanding that when you completely exit a browser, that session is also closed.
To test the second part I accessed my Magento store, added a product into my cart, and completely exited my browser. I reopened my browser and the product was still in the cart. How is that so? Does the PHP garbage collector only run at certain times? I figured that session would be dead therefore couldnt link up to the cookie that is stored on my machine. Any help is appreciated.
Native PHP sessions use a cookie with a 0 expiry, which will be cleared immediately upon browser window being closed. Magento's session cookie (as Emi noted) has a 3 hour expiry and will persist between browser sessions, so closing/opening the browser window won't cause the session to be restarted. The Firefox web developer toolbar, or Chrome's developer tools will allow you to forcibly clear the cookie and restart the session if that's what you want to do.
I should also note that although the cookie name is different and it has an expiry time, under the hood Magento does use PHP's native session support. This means that settings in the php.ini relating to max session lifetime, etc will also affect Magento's sessions.
Also, since Magneto 1.6 (and EE 1.11) there's a feature called persistent shopping cart which establishes a long term cookie for the purpose of maintaining your shopping cart between sessions. If your test to see whether your session is maintained is just looking at the cart this feature may be making it look like your session is much longer than it actually is..
The server can't really tell the difference between closing a window, just staying on the page, or browsing around. At least, not without extra scripting, which isn't built into Magento. If you want to test a session, either wait the 24 minutes, try another browser, or clear all the session files on the server.
Sessions are stored local on the site's server (in most cases in file system, but you can use other type of data storage like: database, apc, memcached...) this is configured in local.xml.
When stored in file system you can find them under /path_to_site_root/var/sessions
I believe you have 3 models that use sessions: 'core/session', 'customer/session' and 'admin/session'
Also you can configure php's garbage collector: http://ca.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime
When you close your browser, if cookie has expire set to 0 it won't be used anymore http://ca.php.net/manual/en/function.setcookie.php
Magento's default cookie is called frontend and I think it has expire set to at least and hour, also you can't modify this cookie from javascript, since it's http only.
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.