16

I have a facebook Iframe application with multiple PHP pages in it.

I have some links that point relatively to the files inside my "iframe folder".

Having some issues with session variables inside the iframe. I set some session variables but they do not persist from one page to another.

This does work on other browsers.

I've been reading that Safari does not support Cross-Domain cookies and this might be the problem , but im not sure how to fix this.

Any help?

Bathan
  • 783
  • 3
  • 9
  • 18

8 Answers8

12

I believe this solution has become obsolete with the latest (6.0 and later) versions of Safari.

Safari by default does not allow cookies to be set from third parties. This affects Facebook iframe applications because the user is accessing a page served from apps.facebook.com but the iframe is being served from yourdomain.com, the "third party" in this case.

There are several several solutions mentioned around the web. The best I've found and one recommended by Facebook in its list of miscellaneous issues is to fake a POST request to yourdomain.com using JQuery. This solution detailed by Anant Garg works in general for different host/iframe domains and needs to be adapted for Facebook apps. The key parts are:

$("body").append('
 <iframe id="sessionframe" name="sessionframe" onload="submitSessionForm()" src="http://www.yourdomain.com/blank.php" style="display:none;"></iframe>
 <form id="sessionform" enctype="application/x-www-form-urlencoded" 
   action="http://www.yourdomain.com/startsession.php"
   target="sessionframe" method="post"></form>');
var firstTimeSession = 0;
function submitSessionForm() {
  if (firstTimeSession == 0) {
    firstTimeSession = 1;
    $("#sessionform").submit();
  }
}

Another solution by Will Henderson is to instrument each link on your page with session information using a Javascript function. Then modify your server code to capture this session information by reading it from GET parameters.

sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Jonathan Berger
  • 1,043
  • 13
  • 17
  • 1
    @UğurÖzpınar Yeah, there's no recourse now except to pass the session between pages. Safari fixed up the faux POST with the recent Google privacy violations fiasco. – kniteli Apr 06 '12 at 00:22
11

I wrote the blog post Dominic refers to in his answer.

The problem is that the default behavior of Safari is to only accept cookies from sites that you visit. This excludes "third party" cookies. Safari treats the page inside an IFRAME as a third-party site, and until you interact with that content (by clicking a link, for example), it will refuse those cookies.

Your PHP code needs to set a cookie on the first page that uses the session in order for that session to persist from one page to another, but if the session variables are in the very first page in the IFRAME, you have a chicken-and-egg problem.

My solution is to retain all of the special Facebook parameters through to the second page loaded into the IFRAME. Because you've interacted with it, cookies set on the second page will persist, and this allows your PHP code to keep whatever state it needs to communicate back to Facebook.

This won't likely help your PHP session, though, so I suggest adding another parameter to links on the first page that allows the second page to look the session up, or otherwise recreate it.

Steve Madsen
  • 13,465
  • 4
  • 49
  • 67
  • Steve, I'm using Single-Sign On facebook authentication. Facebook sets the cookie for my hosted domain to provide single-sign on. But, exactly as you mentioned, safari would reject it. And the app is left with the problem of no cookie from facebook. If I was setting the cookie, it's different scenario. – cdpnet Jul 08 '10 at 23:23
  • Can any one confirm that this solution does not work in recent Safari versions? – Eydun May 09 '12 at 10:30
2

I think the best solution is to manually keep track of the session ID i.e. by using session_id($_GET['session]); Just make sure you do this before calling session_start(); and everything works.

Zorayr
  • 23,770
  • 8
  • 136
  • 129
2

Safari accepts cookies only from the page the user navigates to. The easiest and most effective way to fix this is to redirect the request from landing page of your canvas app to a different page on your domain using top.location.href and redirect the user back to the canvas app from that page.

For example, if abc.php is your landing page and the canvas URL is facebook.com/abc. First redirect the request from abc.php to a different page like xyz.php then redirect again from xyz.php to facebook.com/abc. Don't forget to start the session in xyz.php.

This is the simple fix...

ronalchn
  • 12,225
  • 10
  • 51
  • 61
Liju
  • 21
  • 1
1

With the release of Safari 7, not only 3rd Party cookie is being blocked. Local Storage as well as WebDB, any kind of website data are being blocked. When you go to Safari Preferences (CMD+comma), Under privacy tab, on Safari 7, it now says : "Block cookies and other website", originally was "Block cookies". That confirms the changes.

Other browsers might follow through in the future. Most probably Firefox. Chrome, cough *cough* probably not.

You probably have to employ some workaround using redirection technique or popup similar to what disqus did.

Fred
  • 11
  • 1
1

and thanks for all the input. I ended up solving the problem by appending the "signed_request" paramter on every page. I just put it in as a hidden field and set it in the code behind. That way I managed to get it to work in Safari. Hope it works for you too.

Anders
  • 31
  • 2
  • Thank you for this answer! So easy! =) But since this answer has been downvoted a lot, I wonder what the downsides are? (Guess I'll find out soon...) – Olof_t Feb 27 '13 at 17:18
  • 2
    How did you use the signed_request parameter? Is there a code example? Does this technique work anymore? – Hello Universe Nov 12 '13 at 10:57
0

If you using .NET then there is a much simpler solution to this problem.

Just set cookieless to false in your web.config. Ex:

sessionState mode="InProc" cookieless="true" timeout="60" 

Its a lot easier than posting an iframe, or opening a popup window with the url of the iframe.

kind regards,

David

Christian Specht
  • 35,843
  • 15
  • 128
  • 182
David.
  • 1
  • 2
    I have similar issue with 3rd party cookies in my project. But this solution didn't help me... I tried set cookieless to false, UseUri, AutoDetected. But I receicing exception. Maybe this is a reason: "When you configure an AJAX-enabled ASP.NET Web site, use only the default value of UseCookies for the cookieless attribute. Settings that use cookies encoded in the URL are not supported by the ASP.NET AJAX client script libraries." – Yaroslav Bigus Mar 24 '12 at 08:55
-1

I used this header with PHP, that fix my problems

if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') ) header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
Martin
  • 128
  • 5