I have read a couple of related posts here, but cannot seem to be able to make my script work as intended.
I have a login page where a user logs in. If the password matches, the script writes two values into the $_SESSION
variable: ['loggedin']='yes'
and ['loginname']="username"
.
After successful log in, the user goes to another page that has 2 iframes in it.
One iframe uses external content and does not require authentication (removing this iframe from the page does not change anything).
The other iframe uses dynamically generated content from the same domain and does check whether the session variables are still there.
One of the functions refreshes the content of that dynamically generated iframe.
Once this is done, the session variables are lost. In fact, the session itself no longer exists.
I have session_start();
on every page that is used in connection with this script.
Any help would be greatly appreciated.
I believe this article'll be useful:
http://www.how2guru.com/archives/php-session-problem-while-using-iframe/
The short answer is: in the iframe, start the session like this:
header('P3P: CP="CAO PSA OUR"');
session_start();
EDIT:
Thought I should update this answer, since I stumbled upon on something interesting everyone should know about.
This p3p header hack does not work on safari.
Below I describe my login flow, and how I solved this problem.
My login flow looks like this (page app):
- checking if the current user has a session,
- if not, redirect to the login url (generated by the PHP SDK),
- the login dialog redirects back to a url, where I use the 'code' GET parameter facebook gives me, to get an access token, which I can store for later use. (Saving to the DB and to the session. ) If I'm done with that, I redirect the user to my page app, where everything will work.
- everyone should be happy at this point.
BUT here comes the gotcha.
If a user uses safari, and tries to open this app when the sessions already got destroyed (a few days later for ex.), the following thing will happen:
- The code checks for a session: it finds the user ID (PHP SDK getUser() method), so I first check for an entry in the database.
- Since the user logged in before, he has an entry in the database, so I just grab it and save it to a session, so that future AJAX calls will have all the information they need.
The important thing to note here, is that this code runs in a page tab within an iframe.
So for most of the users the code will work, because of the p3p header hack.
But for safari users it won't.
Safari doesn't care about the given header, it refuses to save the session, hence the user logs in to the app, everything seems to work fine, but the ajax calls won't work, since they won't have any session to work with.
The workaround:
Quite simple actually - Although not too elegant, but hey, it works. -: I check whether the client browser is safari or not, and if it is, I redirect to a custom url, where I start a session - outside the facebook iframe -, then redirect back to the app.
This will create the cookie without a problem, so sessions will be available.
Here, have some code:
Checking the session
(Credit goes to this guy)
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') && !strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome')) {
if (count($_COOKIE) === 0) {
echo '<script>
top.location = "http://www.domain.com/setcookie.php";
</script>';
}
}
setting the session (setcookie.php)
header('P3P: CP="CAO PSA OUR"');
session_start();
$_SESSION = array();
echo
'<script>
top.location = "http://back-to-the-facebook-app.com";
</script>';
I hope this additional trick will help someone.
EDIT2
I didn't try this one out yet, but instead of adding the P3P header, you could just add the following lines to your .htaccess:
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
</IfModule>
With comments:
# ------------------------------------------------------------------------------
# | Cookie setting from iframes |
# ------------------------------------------------------------------------------
# Allow cookies to be set from iframes in IE.
# http://msdn.microsoft.com/en-us/library/ms537343.aspx
# http://www.w3.org/TR/2000/CR-P3P-20001215/
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
</IfModule>
All credit goes for this .htacces code for the guys behind the Yeoman project.
Add the following to each of your pages in the frames:
echo "Session ID: ".session_id();
This should output the Session ID on each page. It is possible a new session maybe getting generated on one of the frames, by checking the above you could rule this possibility out.