We recently migrated from a Windows 2003 server running xamp, to a Centos server running apache with PHP Version 5.3.3.
Originally, the issue was that users were being logged out after about 24 minutes, so I changed the INI variable session.save_path, which resolved the problem. However, some users are still periodically being logged out of our website, seemingly at random. It happens to multiple users using different browsers at different times. Sometimes after having the page sit unused, but sometimes while browsing from one page to another.
Here are our session-related INI settings:
session.save_handler = files
session.save_path = "/var/sessions"
session.use_cookies = 1
;session.cookie_secure =
;session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 86400
session.cookie_path = /
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 86400
session.bug_compat_42 = Off
session.bug_compat_warn = On
session.referer_check =
session.entropy_length = 0
session.entropy_file =
;session.entropy_length = 16
session.cache_limiter = nocache
At first I thought it might have been an issue with the cookie in the browser, as one of the users had his cookie set to never expire even though the code sets the cookie to expire after 24 hours. But, after deleting the cookie and having him log back in, it set the cookie properly to 24 hours, and he had the same issue of being logged out prematurely.
I have created a cron job script that deletes all the sessions every morning at 4am since the sessions have been moved out of the tmp directory.
I discovered today that the sessions on the server aren't being deleted, but a new session with a new session ID is being created when the users log back in, even though they still have an existing session on the server.
Any assistance would be greatly appreciated.
It appears that the problem was being caused by my cookies expiring after my server deleted the sessions.
I had a script setup to manually delete the sessions from the server every morning at 4am, however my cookies were set to last 24 hours. So even after the users logged back into the website and created a new session on the server the cookie didn't have its expiry time updated.
I decreased the cookie duration to 12 hours so that the cookies will always expire before the next time the user is required to log in, and the problem has gone away.
Related
I've been having problems with sessions for some days now in my production environment
I've already tried to find the solution in tons and tons of answers here in stack overflow, but none seem to work for me
User A logs in
User B logs in. Now when you go back to User A
his session was overwritten by User B. So I have two users 'sharing' the
same session.
Side notes:
I have session_start() on the very top of every page using session variables
I'm using https with a valid certificate
Cache is not the problem, I've already tried to set headers to avoid caching
I'm using PHP 5.4 (I was using 5.6 before and downgraded hoping it would solve my problem) and this is my PHP.ini:
session.save_path = "/tmp"
session.cookie_secure = 1
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.entropy_length = 32
session.cache_limiter = nocache
session.cache_expire = 180
session.hash_function = sha256
And this is the basic structure of my authentication page:
session_start();
... // after connection with the database I retrieve id and name
$_SESSION['id_logado'] = $user_id;
$_SESSION['nome_logado'] = $user_name;
I've already double checked every line of code in every page. There is no variable name $id_logado so it should not interfere with that. Cache is probably not the problem because I have headers to avoid caching just after session_start. I've contacted bluehost to ask for help and of course they have no idea and are blaming myself.
I found a solution.
After further investation I noticed that the /tmp folder had only one session file, with a big size. For some reason sessions were not being saved to new files and were being 'added' to the same one.
Solution: I've created a new folder inside my home drive and granted 777 permissions. Updated my php.ini file to use that folder instead of /tmp and now I have tons of sessions being properly generated.
Last night I logged in and the following morning I was still logged in, even if I quit my browser. I want the session to expire after a few hours and I thought that it would work with "session.gc_maxlifetime" set to "1440" and "session.cache_expire" set to "180"
Here is what I could find from PHP.ini
Session Support enabled
Registered save handlers files user
Registered serializer handlers php php_binary wddx
session.auto_start Off
session.bug_compat_42 Off
session.bug_compat_warn Off
session.cache_expire 180
session.cache_limiter nocache
session.cookie_domain no value
session.cookie_httponly Off
session.cookie_lifetime 0
session.cookie_path /
session.cookie_secure Off
session.entropy_file no value
session.entropy_length 0
session.gc_divisor 1000
session.gc_maxlifetime 1440
session.gc_probability 0
session.hash_bits_per_character 5
session.hash_function 0
session.name PHPSESSID
session.referer_check no value
session.save_handler files
session.save_path /var/lib/php5
session.serialize_handler php
session.use_cookies On
session.use_only_cookies On
session.use_trans_sid 0
On our old server we used the same settings and the sessions worked.
The only difference from the old one is the "session.save_handler" that is set to "memcache" on the old server. Also "session.save_path" is different.
Relying on other things and hope them to work is not my thing. :D I think that the best solution would be to implement a session timeout on 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 does also change the session file’s modification date so that the session is not removed by the garbage collector prematurely.
~Foorack
It may help to change gc_probablity to something other than 0.
From the manual for gc_divisor:
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.
If I'm reading from this right, with gc_probability being 0, the garbage collector is never run, rendering gc_maxlifetime useless.
GC is an expensive process for file-based sessions, so it's not a good idea to run it on every request, [edit: so PHP has a built in randomization to run it periodically]
Addendum:
For anything with real security implications, it's likely better to handle invalidating the session in your script, as Max's answer suggests. Also session.cache_expire sets the default expiration for session pages that are sent to the browser, and doesn't affect session storage at all.
Given you've reset gc_maxlifetime, a couple of things i can think of left to check when this happens:
PHP needs a restart
session is recreated/regenerated somewhere
I have some issues concerning the timeout of a php session. I have set the following values during runtime of the application:
session.gc_maxlifetime = 3600
session.cookie_lifetime = 3600
session.save_path = myApplicationPath/tmp
session.use_cookies = 1
session.use_only_cookies = 1
However, my session keeps expiring in about 30 mins. Also, my tmp directory remains empty, so it appears no cookies are actually being set. echoing ini_get("session.save_path") does return the right path though.
Note:
If different scripts have different values of session.gc_maxlifetime but share the same place for storing the session data then the script with the minimum value will be cleaning the data. In this case, use this directive together with session.save_path.
PHP Manual
I'd say that PHP cannot find your save_path or does not have permission to write on that, so it stores session files (not cookies) in the default shared directory (so the site with shortest gc_maxlifetime will remove sessions from all other sites).
I have an application that has been working with session variables no problem. I start the session before the headers on every page that uses when, it has been fine then it seems all of a sudden I'm getting an undefined index error when I navigate to a page other than the one that sets up the session variables. But only on some browsers. Sometimes sessions are maintained and sometimes they aren't.
It seems that cookies aren't being stored some of the time. I've done checks using different browsers and sometimes cookies are stored and sometimes not.
I did an experiment. I was using firefox to use to app and I was keeping an eye on the tmp folder where the sessions are stored. I cleaned it out. Using firefox I started using the app, using all the pages that sessions were in use and at the end I checked the tmp folder and it had one session file in there.
Did the exact same with internet explorer and there are now 7 different session files.
I'm using PHP 5.3.0 with the WAMP stack. Apache 2.2.11. Session support is enabled in my phpinfo().
I call a var dump on the first page and it prints out the session data. On any subsequent pages the session variable is empty.
<?php var_dump($_SESSION); ?>
array(0){}
Can anyone help me figure out a solution to this?
UPDATE - PHP INI SESSION settings
Directive Local Value Master Value
session.auto_start Off Off
session.bug_compat_42 On On
session.bug_compat_warn On On
session.cache_expire 180 180
session.cache_limiter nocache nocache
session.cookie_domain 82.68.26.169 82.68.26.169
session.cookie_httponly Off Off
session.cookie_lifetime 0 0
session.cookie_path / /
session.cookie_secure Off Off
session.entropy_file no value no value
session.entropy_length 0 0
session.gc_divisor 1000 1000
session.gc_maxlifetime 1440 1440
session.gc_probability 1 1
session.hash_bits_per_character 5 5
session.hash_function 0 0
session.name PHPSESSID PHPSESSID
session.referer_check no value no value
session.save_handler files files
session.save_path c:/wamp/tmp c:/wamp/tmp
session.serialize_handler php php
session.use_cookies On On
session.use_only_cookies On On
session.use_trans_sid 0 0
UPDATE - Solution
Because my app was using iframes pulling in pages from another domain (which i created) the cookies i was trying to set were being blocked. Setup a P3P header and the problem seems to be solved!
My suggestion from your previous question still stands: please compare session ids.
The solution might be as simple as your browser not accepting session cookies.
You retrieve the session id by calling session_id(). Do that right after session_start() it should give you a constant value if the session is the same. Otherwise for every request a new session is instantiated.
Also check C:\wamp\tmp. A gazillion files in this directory might indicate fresh sessions for each request.
EDIT Since we've confirmed new sessions per request, it's time to find out whether session cookies are accepted. Check the settings of your browser and confirm that a cookie for your domain (I guess it's "localhost") with the name PHPSESSID can be found.
Do you call session_start() on every page that accesses session data?
Edit: And do you receive the same session ID every time?
Also, could there be some error or warning you're missing (e.g. headers already sent) due to settings?
here is the sense in
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC))
{
$_SESSION['saveddata'] = $row;
}
it rewrites $_SESSION['saveddata'] value on each iteration. may be you meant something like
$_SESSION['saveddata'][] = $row;
it makes sense for $atid = $_SESSION['saveddata']['autotaskid'];
Review your session settings. You have a full list with:
<?php
phpinfo();
?>
Scroll down to the "Session" table.
Particularly, make sure that the session.save_path directory exists and is writeable.
When a new session ID is created with each request, most likely it is an issue with your session paths (save_path and cookie_path) and chances of this happening are greater if you're hosting different applications on one server (shared hosting) and some of these applications also implement sessions.
This results in conflicts in your /tmp directory.
You could change the config of your ini file, but it's best to configure these parameters during runtime.
session_set_cookie_params(0, "/app", ".domain.com");//set session cookie parameters
session_save_path("/home/../public_html/app/sess");//set directory of this app's session data
session_start();//start session
I hope that helps everyone having this issue. #CodeOn
I solved this problem on my local WAMP by clearing out the \tmp directory of old sessions.
The problem is that every so often a page that writes to a Session will cause apache to hang forever for a particular session. Once this error occurs for one user any further modifications to any session of any user will cause the website to hang for this user.
This problem has been my sole focus for days. I have a development VPS running Windows 2003 and default latest version of XAMPP using the standard PHP session handler. The code in question actually runs on two other machines perfectly normally so although my common sense says it’s a web server configuration issue but at this point I am willing to try anything.
On further investigation there are no errors in the Apache, PHP or System event log. Resources are abundant and there is no “AJAX shit storm” or more than a couple writes to a session per page. I have also implemented session_write_close() wherever possible to try and help elevate the problem.
I have checked the session’s directory which is set to “C:\windows\Temp” and found that once a user enters this hanging phase that the corresponding session file is exclusively locked and the only way to resolve this is to stop Apache and wait a few moments for the files to become unlocked and delete them. I am not wondering if deletion is required.
The Sessions themselves only contain 4 bits of information. ShoppingCartID, UserID, UserLevel and Refering URL and are alphanumerical with an occasional slash.
My PHP.INI’s session section is configured like this:
session.save_handler = files
session.save_path = "C:\WINDOWS\Temp"
session.use_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
session.bug_compat_42 = 1
session.bug_compat_warn = 1
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 4
I have tried everything I can think of and the whole problem is now a blur to me. Any ideas would be appreciated and thanks for your time reading this :)
It could be your session files getting locked by Windows or some php.ini settings not done properly. Please SEE HERE
Almost want to say its the lock files.
Is it possible your app internally requests a page from the same site again internally? You could be hitting a race condition of sorts where page A fires up, locks the session, and then somehow triggers a request to itself, or page B, which also tries to re-start the session, which is now locked, and the request hangs.
Otherwise, if the hang is caused by the session file being locked, I'd suggest using something like SYSInternal's 'Handle' to get a list of what processes are using the session file in question.