I have observed my php application behaving rather strangely on the server that it is running on. When a user first visits the application, and clicks on a link with an absolute path, the session data is cleared.
I have recreated the problem as simply as possible. The code can be found below.
I have solved this problem by removing all absolute links in my application, I am simply looking for an explanation of this behavior.
To recreate the problem:
click 'login'
click 'relative link' and observe that the session still has the 'logged_in' variable set
click 'absolute link' and observe that the session data appears to be missing
click your browser's back button and observe that the session data has returned
click 'absolute link' and observe that the session data is missing again
click 'home (relative link)' and observe that session data is missing this time
click 'login' to reset the session data
click 'absolute link' again and observe that the session data was not cleared this time
Some important things to note:
This is not a problem locally on my
mac running MAMP with php 5.3.2,
but is a problem on a server with
php 5.2.14 and a different server running 5.3.2
clicking the absolute link, and then the relative home link without login prevents the problem from ever occurring once you do log in.
once the problem is solved by the method just mentioned, it can only be recreated by navigating to a different domain, clearing your browser's cache and navigating back. Clearing the cache without leaving the page will not work.
this is also a problem if using a absolute path when redirecting using header('Location: ...')
index.php:
<?php
session_start();
print_r($_SESSION);
?>
<br/>Absolute link
<br/>Relative link
<br/>Log in | Log out (reset session)
page.php:
<?php
session_start();
print_r($_SESSION);
?>
<br/>Home (relative link)
login.php:
<?php
session_start();
$_SESSION['logged_in'] = true;
header('Location: index.php');
logout.php:
<?php
session_start();
$_SESSION = array();
session_destroy();
header('Location: index.php');
At least in your example the pages are switching between two domains (rhun.ithaca.edu and www.ithacahealth.org). You'll notice that if you click "Log in" on both domains, then you'll have logged_in=1 in all cases. Anyway, that's the primary cause of the problem - two different domains.
Session cookies does not differ from any other cookies (from a browser's point of view), so they are subject to the same limitations - the relevant one being that you have to be on the same domain. You can change the session cookie settings with session_set_cookie_params() (that has to be done before session_start(), but even so you cannot allow the same cookie to be read from a different domain, only from a subdomain, if you require it.
Also, I don't know if it is relevant, but keeping the webpage on a singe domain/subdomain might help a little with search engine optimization - especially in cases where there is different content between the domains/subdomains, search engines might consider them to be different webpages and split their pagerank between them.
Solved:
Thanks to Nouveau for pointing out that a cookie can only be used for one domain and The Scrum Meister for asking if I always access the site with a www.
The problem was created by starting at http://myserver.com and following the link to http://www.myserver.com
The Session was initialized for http://myserver.com and then again for http://www.myserver.com
Related
I m creating a very simple PHP-based program for warehousing but quite complicated back-end process.
So here is the situation:
I have the login page that directs to authorization page where it set the session_name for the first time, session_start() and set the session variables.
After the authorization page, it goes to the main.php page that is a table with left hand side for menu (links) that I also did session_name() <-- same name as the one created from (1), and start the session.
On the right hand side of the main page is the iframe that display the page when user click the links on the left. I also did session_name() <-- same name as the one created from (1), and start the session.
Problem:
main.php is ok, it reads the session variable perfectly, but the iframe couldn't get the session variables (i tried to print_r($_SESSION), and came up empty). I tried var_dump(session_name("abc")), where "abc" is the session name that i used in (1), and it does show "abc", tried (isset($_SESSION)) and returns true... so I don't know what am I doing wrong...
EDIT:
I m sorry guys, i think i may have found the culprit... it is a logic error on my side... i have this condition to check every php page i created to destroy session when the user level is not authorized to use this current page. My bad.. thanks so much for your help guys!!
Make sure that session_start() is on all the pages:
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
see PHP manual reference
To control the contents of the $_SESSION try to put in all ifreame pages the code:
<?php
session_start();
echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
Did you use session_start() at the top of the page in both the iframe as well as main.php?
You need to put session_start() on the top of the iframe too.
This might solve your problem: php session & iframe
Additionally: Nothing is simple if you're using iframes to display large portions of your webiste. You might want to consider not using them.
I had the same problem with multiple iframes on one of my PHP webpages.
In my case, some AJAX calls to PHP endpoints were being made to www.example.com when the page was loaded using http://example.com. If you are NOT consistent with the domain path, you may have session issues since a request from www.example.com is technically from a subdomain as oppose to being made directly from http://example.com. You can avoid this problem altogether by always using relative paths to your PHP based API when making AJAX calls in JavaScript.
I found this was the case by inspecting my cookies in Chrome. I noticed two different cookies with a different PHP session ID in them. One was set for www.example.com while the other was set for example.com
As mentioned in some of the other answers, you can always set the session cookie domain to work on all of your subdomains along with your main site by using the following:
ini_set("session.cookie_domain", ".domain.com");
PHP by default will set a new session per domain / subdomain. Hope this helps!
I am currently developing two web sites, and debugging them by connecting to localhost.
The first site is referenced with http://localhost/web1 and the second is referenced with http://localhost/web2.
I have created a login script for each in which three domain-specific session variables are set, e.g.:
$_SESSION['web1_user']
$_SESSION['web1_login']
$_SESSION['web1_sessionID']
However, when I log in to both sites on the same browser, then log out of one site (which fires session_destroy(), I am automatically logged out of the second site as well.
Any ideas as to how I might resolve this problem would be very much appreciated. :(
Ahhh, the pleasures of shared hosting!
The best thing to do is simply use a different browser for each site whenever you actually require being logged in to both sites simultaneously...
To explain why this is important, you must understand the following, however:
Session variables are stored on the server, with a keyed reference on the server and a cookie on your browser. Once you unset and destroy either of the two, a match can no longer be made - and your session is gone!
session_start();
session_unset();
session_destroy();
The above will kill all session variables linking the server to your browser (on the server side).
The way to manage this easily is to make session variables into another set of arrays:
$_SESSION["site1"] = array( $user_id, $session_id );
$_SESSION["site2"] = array( $user_id, $session_id );
You could of course make it fancy:
$_SESSION['site3']['userID'] = 'someuserid';
$_SESSION['site3']['sessionid'] = 'somesessionid';
Then when you logout from site 1
session_start();
unset($_SESSION['site1']);
In this case, you have created a separate session management system for each site (using a two-dimensional array, the top layer of which is keyed by your site's identifier). This makes it so that each site manages a separate set of session variables - and when you destroy one, you do not touch the others.
However, I realllllllllly recommend using different browsers instead (or in addition)...
I recently solved a problem which is related to your question. Originally, I was looking for an implementation similar to what you are describing, and after doing quite a bit of searching around - this is what I came up with:
Site 1 :
ini_set("session.cookie_domain", "yourdomainname");
$some_name = session_name("some_name");
$domain = 'your domain name';
session_set_cookie_params(0, "/", $domain);
session_start();
$_SESSION['user']=$_POST['user'];
$_SESSION['password']=$_POST['password'];
Site 2 :
$some_name = session_name("some_name");
ini_set('session.cookie_domain', 'yourdomainname');
session_start();
echo $_SESSION['user'];
echo $_SESSION['password'];
This change worked well for me - and my guess is that it will also help you.
Use
session_name('web1');
before session_start();
Set a different session name in each app, either via session_name() or via session.name.
you can use this
ini_set("session.cookie_domain", ".example.com");
You need to make a different host for different site
in this case you have two site running on same host called localhost so for same host name sessions are shared.
Include the file with the session start in the second domain.
web1 contains the session start file, web2 include('../web1/session.php');
You can use different session name in all website like for first website you have used $_SESSION['web1_user'], $_SESSION['web1_login'], $_SESSION['web1_sessionID'] then second website you can use $_SESSION['web2_user']
I have already face this problem and solved it using different name of session.
Bez sessions are shared in the same browser, so if you logout from one tab, the other tabs will be logged out,
Example: I login in Chrome, and I open in another Chrome, the Sessions are shared, so if i logout from one, the other one gets logged out automatically!
I have secured pages that all check for a set session variable to determine logged in users, pretty standard stuff. Where I run into problems is when I submit form information to a backend page that will process that data and then redirect to a success/failure confirmation page. In that time the session gets lost, at least the session with the variable. The session is still around because I can manually navigate to a secured page after and it works. Just auto redirects from a backend page to a secured page or a link on one of the unsecured pages after a redirect from the backend will fail. It may or may not be related, but after visiting multiple secured pages or doing one of the operations that use the problematic backend pages, there are two session cookies on my computer from the domain-- one registered to domain.com and the other to www.domain.com. At the end of my wits about this, thanks.
I see two problems here, but they're related.
The first is that you seem to be bouncing between secured (https://) and un-secured (http://) pages. Cookies aren't supposed to be shared between those, so that's why your session appears to break (PHP sets a cookie with the session ID).
The other is closely related and that is sharing between domain.com and www.domain.com. Cookies can share in one direction, but not the other. Don't worry about which: just pick one hostname and stick with it. Then check that you're setting the session's cookie domain to the correct one.
You must call session_start() from your PHP page before you output anything, preferably at the start of the page.
If the session has been already created, it will resume it for that page.
http://php.net/manual/en/function.session-start.php
I need to use the same session in different subdomains.
First I put
php_value session.cookie_domain ".aaaa.com"
on .htaccess file and upload it to root path.
when I need to use sessions. I just call
session_start();
Sometimes it works but sometimes it doesn't.
I tested this and found that.
If I go to login page the first time, then login and go to subdomain page. It works!
If I go to subdomain page and click to login page and go back to subdomain page by javascript window.location = 'http://sub.aaaa.com'; it does not work!!
If I login on 2 web browser with the same account it does not work!!
Are there another way? Or how do I fix this problem. I want my website to use a single login.
Make sure you have session_start() on every page you are using sessions, including some that might not be visible to the user.
If you are using two web browsers the sessions are independent from each other, and this is by design.
To debug your #2 problem, use an HTTP monitor such as HTTPFox to view the headers coming to/from the server as you log in and surf around, make sure the cookie is being properly set with the correct domain and path restrictions.
Probm #3 - I'm not sure what you're getting at. Are you using two seperate browsers (say Firefox and Chrome?), or do you mean you're using two windows/tabs of the same browser? For the first, two different browsers will not share cookies, so you can't share a single session between them, without doing some hacks to manually transfer cookies between them.
As for two different tabs/windows of the same browser, such an implementation depends on your login logic. If the login script starts a new session unconditionally, then you second login attempt will get a completely seperate session from the first login, and most likely overwrite the first login's cookie as well.
I have a site which I have been testing in a sub-folder of my client's site-root.
I had no log in problems during testing, but then I moved the new site files from a sub-directory to the main site root, and now I'm losing my logged in state after almost every page refresh in secure areas.
I am running a $_session based login system that refreshes the session id on every page load, with a comparison value stored in the MySQL database.
Does anyone have suggestions for what could be causing this problem?
krico was right in suggesting that the cookie path may be the cause (but the solution proposed seems a bit daft) however you've said that is not the case.
Check to see exactly what cookies (name, path, expiry, flags) are being set and returned by using iehttpheaders (MSIE) LiveHeaders (Firefox) or using a network sniffer like wireshark. Then ask the question again providing details of what you found out.
C.
Cookies are usually path relevant. Your previous sub-directory based site was probably setting the cookie (that binds the browser to the user) only for that sub-directory.
A way to fix it is to put a redirection page on the old subdir that adds a cookie to '/' and then redirects to new site on root.
If you change session id you will loose all data stored in previous session. You must set session name after every session start command
<?php
session_name('AnySessName');
?>
or use other mechanism to store your variables cross sessions.