Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php session & iframe

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.

like image 270
Uno Mein Ame Avatar asked Jan 21 '12 23:01

Uno Mein Ame


People also ask

What is a PHP session?

❮ Previous Next ❯ A session is a way to store information (in variables) to be used across multiple pages. Unlike a cookie, the information is not stored on the users computer.

What is PHP session and how it works?

The browser sends a request to the server. PHP responds by sending a unique token that identifies the current session. This is known as the session ID. In all subsequent requests, the browser sends the session ID to say, "Hey, it's me again." All other data related to the session is stored on the web server.

What is PHP session with example?

PHP session is used to store and pass information from one page to another temporarily (until user close the website). PHP session technique is widely used in shopping websites where we need to store and pass cart information e.g. username, product code, product name, product price etc from one page to another.

How do you start a PHP session?

You can start a session in PHP by using the session_start() function. This function will, by default, first check for an existing session. If a session already exists, it will do nothing, but it will create one if there's no pre-existing session available.


1 Answers

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.

like image 133
ZeeCoder Avatar answered Sep 25 '22 13:09

ZeeCoder