This is a variant of a common php problem that seems to defy solution (and common sense): when a user switches between http and https on my site, php dumps the contents of the session. This would be bad enough, except for the fact that the site works fine when I run it under the domain test.mysite.com. The problem only shows up when I run it under www.mydomain.com, and only on our new server. The code worked just fine on my old machine!
Both servers are running CentOS, with the troublesome one on Rackspace CloudServer.
Any suggestions?
Edit
Just to make something clearer: the session actually gets cleared when going to a secure page. I can't go back to an unsecured page to view the original contents of the session, even though the session id's haven't changed.
Sounds like you've fallen victim to the curse of the dreaded php.ini file. Some cookie parameters are getting set differently.
I would ensure that the php.ini files in development and production are EXACTLY the same, you are running the same version of PHP, ideally the same build.
EDIT: ok, so it's not necessarily a difference in php.ini.
Have a look at the domain you're using for your cookies. If you set a cookie without explicitly setting the domain, it is the current domain only.
If this is www.example.com, users who visit http://example.com/ then are redirected to https://www.example.com/ WILL LOSE THEIR COOKIES.
Why? Because the cookie is being set for the exact domain, and won't be sent by the browser to a different host name.
The same is true if you run the site on multiple names. Be sure that you only run the site on exactly one name. If a user arrives on any other name, redirect them with a permanent redirect to the One True Name, before setting any cookies.
Can you try setting the secure flag to false using this function?
<?php
session_set_cookie_params(0,"/",".mysite.com",false,true);
?>
More info here: http://us2.php.net/manual/en/function.session-get-cookie-params.php
Related
I have a website (www.mysite.com) with a private backend (www.mysite.com/admin)
When I'm adding content to the site in the admin area and switch back and forth between tabs in the same browser window to see the content I'm editing, my session is getting expired/ended/terminated and I'm redirected to the login page again.
I have used the same code many-many times before on many web sites (this is a CMS I've made by myself) without a problem. The only thing I can think of is that this particular website is hosted on a different web server and maybe it's a matter of a php.ini setting or server configuration. Any ideas?
Have you checked your browser cookies? (the actual client-side ones?) or tried your luck with another browser? It may sound a bit strange, but I had a similar problem and in my case it had to do with these cookies. It may be worth figuring out because of your odd problem. As you might know the phpsession value is stored in that cookie and so is the domain.
Good luck!
This could be a result of several things, but my first instinct is to check and see if the session cookies are expiring very quickly. Sometimes server headers may change expiry values. You may also want to check the cache headers being sent by the server. If you are using asynchronous functionality on the admin area, it is possible that somehow the server is changing the expiry of cached files which could affect this.
I am eager to see the solution to this.
A few things to check:
session.cookie_lifetime setting - Possibly too short; 0 is the default and keeps the cookie until the browser closes
session.cookie_path setting - You'll want this to be '/'
Session storage - Make sure the session data is being written.
Explicitly call session_close() if your sessions are stored in a database. That will ensure they are written before your objects and database resources are destroyed.
If serving through any sort of proxy, check for any changed header information.
If caching, check your dynamic pages (requiring sessions) are being served by your web app and not the cache.
If testing with your local /etc/hosts, first clear your cookies so the new server's cookies are fresh and don't conflict.
Confirm in your browser that the cookie is in fact being stored. Maybe it's not actually coming back in the header.
I had a problem like this before. I was just uploaded a site from my localhost to a remote host, and I haven't change the nameservers yet. The hosting company provided me with a temporary url to be able to see my website. The problem was that this url was like this https://server_name.grserver.gr:8443/sitepreview/http/my_site.gr/, the result was that any browser didn't accepted the session cookie because I didn't had an SSL sertificate so the sessions didn't worked at all. I browsed a little the plesk panel and I found an other temporary url that was using http protocol, with this everything was ok. So if you are using https try to check if you have a problem with your ssl sertificate (for expample if it has expired). You said the problem occurs when you login in the admin page, do you switch then to https?
There could be several reasons. As there is no code or no details about the site provided , I am assuming that the problem might be if you are using htpasswd. If u are using htaccess authentication, then your session gets destroyed.
From experience, I can tell you a few things.
First, sessions need to be started with
session_start();
At the top of every page you want to use sessions.
Next, to save session data, you need to call another function to tell php that you are saving stored data. That function is
Session_write_close();
That function is needed on the bottom of the page when you are finished writing data to a session and want it saved for later use.
With those two combined, that should allow you to properly write to a session, save the data you entered into it, and access it later on your site.
Good luck.
The problem has been found after reading this topic.
I had a custom php.ini in the root dir and apparently it was interfering with the $_SESSION. I don't know why but after deleting it everything works fine.
At first it seemed as if the problem was opening pages located in different sub-folders in several browser tabs however it narrows down to a sub-folders issue and the fact that the $_SESSION wasn't accessible across them.
I'd like to thank everyone that put some time into trying to help me figure this out.
This morning my local php starts behaving strangely: the session ID changes on each request (making sessions unusable).
The code:
<?php
session_start();
The same page is available through "localhost" and "test" which is a /etc/hosts entry for localhost.
Requesting this same file on "localhost": the PHPSESSID cookie stays the same; on "test" it changes on every request.
Absolutely nothing changed in my code (no BOM or buggy code) or in Apache's config. I may have updated PHP (5.4.4), but reverting to the previous version (5.4.1) showed the same behavior. The same code running on a remote server (php 5.3) has been running ok for ages.
It's probably a bug in PHP :( but before reporting, I want to be sure I didn't overlook anything.
Any idea?
Thanks for your amazingly fast answer.
In fact the browser works fine, everything is working fine, even PHP.
I just forgot I added a .htaccess clearing all cookies to upload to a CDN. The only thing I didn't check was the .htaccess.
I feel stupid (and tired).
Thanks again.
Install some software watching HTTP headers like
Live HTTP Headers Firefox addon https://addons.mozilla.org/en-us/firefox/addon/live-http-headers/
WireShark sniffer http://www.wireshark.org/
and check whether
Server sends the cookies as it should
Browser sends them back.
Probably the Cookie header contains settings which make Browser not to send it back, and therefore server generates a new cookie (new session) for every request.
Especially check the path setting of the cookie you send.
Also, it might be some new policy in browser, or a security plugin, or maybe antivirus... try different browser, or bare curl program, and disable web shield of your antivirus if applicable.
This has been driving me mad for the last few hours. It seems like PHP/Apache/Pound/Haproxy (can't really tell) insists on redirecting a page to the same scheme/domain I was on before, even though I clearly state it should be a different one.
Background: we usually have an http:\\www.example.com domain coupled to an https:\\secure.example.com secure domain (note the different subdomains). This makes our development easy, since we don't have SSL certificates for all our developers/projects and we can just check if the URL starts with 'secure.'. For this project, the client wants https:\\www.example.com as a secure domain, so I thought: no problem, I'll just change the logic to detect that for production. That part is working fine.
However, in some cases the user needs to be redirected from secure to non-secure, e.g. when having logged in and being redirected to the homepage. I've narrowed it down to this simple test-case (note: secure and non-secure public directories are simply symlinks to one another):
<?php
// this is our server-specific way of detecting secure/non-secure in production
if (isset($_SERVER['HTTP_X_SSL_CIPHER'])) {
header("HTTP/1.1 Moved permanently", true, 301);
header("Location: http://www.example.com/test.php");
}
echo 'bubbles!';
You'd expect it to redirect once after calling https:\\www.example.com/test.php, and then echo "bubbles!". However, my browser insists on redirecting back to httpS:\\www.example.com/test.php, thus causing an endless loop.
If I replace the header call with an HTTP meta refresh and/or javascript redirect all works fine, but I really want it to work with the location header. Apache/PHP/Pound/Haproxy seem to be deciding for themselves that I should just stick to the secure domain, even though I'm explicitly telling them not to.
One other interesting thing to note is that the reverse (redirecting from non-secure to secure) seems to be working fine. Also, on other sites (on the same server) that use the https:\\secure.example.com scheme, everything is working fine too, presumably because the subdomain is different.
Does anyone have any idea why this could be happening, and what is causing it? Our server setup is: Pound to distribute https requests to hidden webservers on port 8080, then haproxy to do the same for non-secure on port 80 (and some other stuff like IMAP), and behind that just some plain vanilla Apache webservers.
The only thing I can think of is that somehow the load balancers are messing things up, but that doesn't make sense since the replies from the webservers are sent directly back to the client AFAICT... any ideas, anyone?
N.B. replaced the slashes in the examples with backslashes, or SO thought I would be posting "too many links". They're not links, they're example domains. If I wanted to post a link, I'd have added an anchor.
Found it; Pound defaults to rewriting any location header to "what was originally requested" if the domain names match (which they did in this case). See "RewriteLocation 0|1|2" in the ListenHTTPS section; should be set to 0 ("don't do this") in my case.
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 not exactly sure the question I should be asking. Sorry!
I'm working on re-doing my web site so as to be using PHP5. The server lives in a buddy's basement and I just ssh in to do my coding and view the pages just like any other page out there.
I keep track of login details in $_SESSION.
When I'm sitting at my home machine I can log into the site and everything is as I expect it in terms of the SESSION being available on all pages. When I log in on my work machine, I get a successful log in and can see the SESSION variables, but as soon as I go to another page the SESSION is gone as evidenced in session_id().
My previous web site built in PHP4 (and tweaked to keep PHP5 happy) does not exhibit this behavior allowing me to log in as expected at either location before and after the change to PHP5.
I guess I'm just looking for a clue as to what to explore next... Of all the puzzles I've encountered while teaching my self to code this one appears on the face, just crazy.
I think Jake is on to something about the cookies. Make sure your browser at work is set to accept cookies from that domain. Make sure there isn't any antivirus/antimal-ware that has disabled this. I'd use fiddler to watch the traffic and headers on your work machine, and your home machine. you should be able to quickly spot the difference since it sounds like a client issue.
It could be that the computer at work isn't supporting session cookies. It's been a while since I last read about PHP Sessions, but from what I remember...
session_start() is called.
php checks to see if the browser has sent a cookie to the server (a unique identifier needs to be supplied.
if so, it then checks checks on the server for a file with the name of the session id
if successful, it parses the file and sets the variables into the $_SESSION array
Notice that step one of this process is to actually start the session with session_start() this needs to be called before any output at all.
Have you got session_start() before output?
Do you make use of session_start() in your various php files ?
One way to get around this problem could be to store your sessions in a database.
This DevShed article by Rich Smith is a good place to start:
Storing PHP Sessions in a Database
The session is no longer saved as a file on the server, but rather an entry in the DB, and should solve any cookie issues.
Are the settings in php.ini for session.auto_start the same in both ini's?
See http://de3.php.net/manual/en/session.configuration.php#ini.session.auto-start