Safari Drittanbieter-Cookie-Iframe-Trick funktioniert nicht mehr?


137

Dies ist also die x-te Rache der Frage "Wie bringe ich Cookies von Drittanbietern dazu, in Safari zu funktionieren?", Aber ich frage erneut, weil ich denke, dass sich das Spielfeld geändert hat, möglicherweise nach Februar 2012. Einer der Standardtricks, um den 3. Platz zu erreichen Party-Cookies in Safari waren wie folgt: Verwenden Sie Javascript, um einen versteckten Iframe zu veröffentlichen. Es hat Safari (früher) dazu verleitet zu glauben, dass der Benutzer mit den Inhalten von Drittanbietern interagiert hat, und so das Setzen von Cookies ermöglicht.

Ich denke, diese Lücke wurde nach dem milden Skandal geschlossen, als sich herausstellte, dass Google diesen Trick mit seinen Anzeigen verwendet hat. Zumindest konnte ich mit diesem Trick keine Cookies in Safari setzen. Ich habe einige zufällige Internet-Postings entdeckt, in denen behauptet wurde, Apple arbeite daran, die Lücke zu schließen, aber ich habe kein offizielles Wort gefunden.

Als Fallback habe ich sogar versucht, den Hauptrahmen eines Drittanbieters so zu gestalten, dass Sie auf eine Schaltfläche klicken mussten, bevor der Inhalt geladen werden konnte, aber selbst diese direkte Interaktion reichte nicht aus, um Safaris kaltes, kaltes Herz zum Schmelzen zu bringen.

Weiß also jemand mit Sicherheit, ob Safari diese Lücke tatsächlich geschlossen hat? Wenn ja, gibt es andere Problemumgehungen (außer das manuelle Einfügen einer Sitzungs-ID in jede Anforderung)?


21
Eine dritte Partei iframe verwenden , die Cookies ist sicherlich muss nicht per Definition ein Angriff auf die Sicherheit! Wir betreiben einen Webshop, der in einem Iframe auf einer Vielzahl verschiedener Domänen verwendet wird, und haben in letzter Zeit alle möglichen Probleme mit Safari. Daher bin ich auch sehr an der Antwort auf diese (legitime) Frage interessiert.
Mscha

14
So ziemlich jeder, der Facebook-Apps erstellt, hat dieses Problem mit Safari. Facebook-Apps werden in einem Iframe ausgeführt und stammen per Definition alle von Drittanbietern. Aus diesem Grund ist die Unterstützung für Safari in Facebook-Apps etwas uneinheitlich: Sie können keine Cookies verwenden.
gs hurley

Ich kann dieses Problem auf Safari 5.1.7 nicht reproduzieren. Es akzeptiert das Cookie von meinem Facebook-App-Iframe mit der Standardeinstellung "Keine Cookies von Drittanbietern". Chrome 19.0.1084.46 mit derselben Einstellung blockiert jedoch das Cookie.
Evgeny Shadchnev

4
Chrome 19+ mit der (zum Glück) nicht standardmäßigen Option "Cookies und Site-Daten von Drittanbietern blockieren" ist aktiviert / noch härter / als die Standardeinstellung von Safari "Cookies von Drittanbietern und Werbetreibenden blockieren". Selbst wenn Sie in Chrome die Domain eines Drittanbieters besuchen und Cookies gesetzt haben, werden diese nicht an den Iframe übertragen. Der Benutzer muss in seinen Chrome-Sicherheitseinstellungen tatsächlich eine "Ausnahme" für Ihre Domain hinzufügen.
Aaron Gibralter

Was meinst du mit Feb 2012? Gibt es eine technische Änderung in Safari oder eine Gesetzesänderung?
flüssig

Antworten:


51

Ich wollte hier nur eine einfache funktionierende Lösung hinterlassen, die keine Benutzerinteraktion erfordert .

Wie ich in einem Beitrag sagte, machte ich :

Grundsätzlich müssen Sie Ihre Seite nur auf top.location laden, die Sitzung erstellen und sie zurück auf Facebook umleiten.

Fügen Sie diesen Code oben in Ihren Code ein index.phpund setzen Sie ihn $page_urlauf die endgültige Registerkarte / App-URL Ihrer Anwendung. Sie werden sehen, dass Ihre Anwendung problemlos funktioniert.

<?php
    // START SAFARI SESSION FIX
    session_start();
    $page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
    if (isset($_GET["start_session"]))
        die(header("Location:" . $page_url));

    if (!isset($_GET["sid"]))
        die(header("Location:?sid=" . session_id()));
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid):
?>
   <script>
        top.window.location="?start_session=true";
    </script>
<?php
    endif;
    // END SAFARI SESSION FIX
?>

Hinweis: Dies wurde für Facebook erstellt, funktioniert jedoch in anderen ähnlichen Situationen.


Bearbeiten 20.12.2012 - Unterzeichnen der signierten Anfrage:

Der obige Code verwaltet die Post-Daten der Anforderungen nicht, und Sie würden die signierte_Anforderung verlieren, wenn Ihre Anwendung auf einer signierten Anforderung beruht. Probieren Sie den folgenden Code aus:

Hinweis: Dies wird noch ordnungsgemäß getestet und ist möglicherweise weniger stabil als die erste Version. Die Verwendung erfolgt auf eigenes Risiko / Feedback wird geschätzt.

(Vielen Dank an CBroe , der mich hier in die richtige Richtung gelenkt hat , um die Lösung zu verbessern.)

// Start Session Fix
session_start();
$page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
if (isset($_GET["start_session"]))
    die(header("Location:" . $page_url));
$sid = session_id();
if (!isset($_GET["sid"]))
{
    if(isset($_POST["signed_request"]))
       $_SESSION["signed_request"] = $_POST["signed_request"];
    die(header("Location:?sid=" . $sid));
}
if (empty($sid) || $_GET["sid"] != $sid)
    die('<script>top.window.location="?start_session=true";</script>');
// End Session Fix

Vielen Dank, funktioniert wie ein Zauber und ist so einfach in vorhandene Apps zu implementieren :-)
SamiSalami

Dieser funktioniert also im Grunde genommen mit ein paar Weiterleitungen, oder?
Aaron Gibralter

1
@hugoderhungrige Gern geschehen. Ich habe gerade eine neue Version hinzugefügt. Sie können sie gerne überprüfen, wenn Sie die signierte Anfrage für Ihre Apps beibehalten müssen.
Diogo Raminhos

1
@CBroe Vielen Dank für den Hinweis! Sie hatten Recht, es funktioniert, da der Benutzer mit der zweiten Anfrage bereits eine Sitzung gestartet hat! Ich denke, dass "der schlimmste Blinde derjenige ist, der nicht sehen will".
Diogo Raminhos

1
@ Whiteagle Können Sie einen Testfall bereitstellen, der 1 und 2 demonstriert?
Gajus

35

Sie sagten, Sie wären bereit, Ihre Benutzer auf eine Schaltfläche klicken zu lassen, bevor der Inhalt geladen wird. Meine Lösung bestand darin, mit einer Schaltfläche ein neues Browserfenster zu öffnen. In diesem Fenster wird ein Cookie für meine Domain gesetzt, der Öffner aktualisiert und dann geschlossen.

Ihr Hauptskript könnte also so aussehen:

<?php if(count($_COOKIE) > 0): ?>
<!--Main Content Stuff-->
<?php else: ?>
<a href="/safari_cookie_fix.php" target="_blank">Click here to load content</a>
<?php endif ?>

Dann sieht safari_cookie_fix.php so aus:

<?php
setcookie("safari_test", "1");
?>
<html>
    <head>
        <title>Safari Fix</title>
        <script type="text/javascript" src="/libraries/prototype.min.js"></script>
    </head>
    <body>
    <script type="text/javascript">
    document.observe('dom:loaded', function(){
        window.opener.location.reload();
        window.close();
    })
    </script>
    This window should close automatically
    </body>
</html>

Ich dachte an so etwas. Funktioniert einwandfrei. Ich lade es zusammen mit dem Berechtigungsdialog. Vielen Dank!
Vwoelm

Scheint so, als würde dies auch die Einstellungen von Safari umgehen, und sobald es allgemein bekannt ist, wird es genau wie die anderen "Lösungen" gestrichen. Ich suche nach einer völlig anderen Lösung, da es ziemlich offensichtlich wird, dass Cookies von Drittanbietern jetzt der Teufel sind, selbst wenn sie in geeigneter Weise verwendet werden.
LocalPCGuy

1
Diese Lösung hat bei mir funktioniert. Ist das Popup jedoch erforderlich? Könnten Sie Ihren Iframe auf die Safari-Seite umleiten, den Cookie setzen und dann mit Weiterleitungs-Headern zum Spiel zurückkehren? Oder benötigen Sie das Popup, damit der Benutzer direkten Kontakt zum Server hat?
Anthony Hastings

das hat gut funktioniert; Glücklicherweise war das Drücken eines Knopfes zum Initialisieren in meiner App keine große Sache.
Kleinere

@LocalPCGuy Ich bin mir nicht sicher, ob es wie andere Lösungen gestrichen wird, da ein Benutzer tatsächlich auf die Seite klicken / mit ihr interagieren muss, damit das Popup nicht blockiert wird. Diese von Safari entwickelte Lösung scheint gut zu funktionieren: Werbetreibende können keine geheimen domänenübergreifenden Cookies setzen, und für eingebettete Apps muss ein Benutzer interagieren, bevor er ein Cookie setzen kann.
Aaron Gibralter

15

Ich habe Safari mit einem .htaccess ausgetrickst:

#http://www.w3.org/P3P/validator.html
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"NOI DSP COR NID CUR ADM DEV OUR BUS\""
Header set Set-Cookie "test_cookie=1"
</IfModule>

Und es hat auch bei mir aufgehört zu arbeiten. Alle meine Apps verlieren die Sitzung in Safari und werden von Facebook weitergeleitet. Da ich es eilig habe, diese Apps zu reparieren, suche ich derzeit nach einer Lösung. Ich werde euch auf dem Laufenden halten.

Bearbeiten (06.04.2012): Anscheinend hat Apple es mit 5.1.4 "behoben". Ich bin sicher, dass dies die Reaktion auf die Google-Sache ist: "Bei der Durchsetzung der Cookie-Richtlinie ist ein Problem aufgetreten. Websites von Drittanbietern könnten Cookies setzen, wenn die Einstellung" Cookies blockieren "in Safari auf die Standardeinstellung" Cookies blockieren "gesetzt wurde." Von Dritten und Werbetreibenden ". Http://support.apple.com/kb/HT5190


1
Anscheinend hat Apple es mit 5.1.4 "repariert". Ich bin mir sicher, dass dies die Reaktion auf die Google-Sache ist: "Bei der Durchsetzung der Cookie-Richtlinie ist ein Problem aufgetreten. Websites von Drittanbietern könnten Cookies setzen, wenn die Einstellung" Cookies blockieren "in Safari auf die Standardeinstellung" Cookies blockieren "gesetzt wurde." Von Dritten und Werbetreibenden ". Support.apple.com/kb/HT5190
vwoelm

1
Daher denke ich, dass dieser Kommentar von vwoelm der Antwort, nach der ich gesucht habe, am nächsten kommt. In erster Linie wollte ich die Bestätigung, dass Apple die Lücke endgültig geschlossen hat, und der Verweis auf den Apple-Support-Artikel ist genau das. Der zweite Teil meiner Frage betrifft jedoch noch. Welche Optionen gibt es für Problemumgehungen? Natürlich können wir Sitzungs-IDs als GET / POST-Parameter codieren, aber was sind die anderen Optionen. Funktioniert lokaler Speicher in diesem Zusammenhang? Flash-Cookies?
gs hurley

@vwoelm: das ist in der Tat die Antwort, nach der ich gesucht (aber nicht gehofft) habe. Wenn Sie dies in eine Antwort anstelle eines Kommentars einfügen, werde ich Ihnen das Kopfgeld zuweisen.
Mscha

3
@gshurley Ich denke, das Senden von Sitzungs-IDs über GET / POST-Parameter ist die einzige Option. Es ist unsicher, aber Facebook zwingt uns trotzdem, Canvas-Apps ohne SSL bereitzustellen. Und außerdem, was bekommst du wirklich, wenn du eine Facebook-App hackst, haha? Wir sind Apple ausgeliefert und sie befinden sich derzeit im grausamen Modus.
Hekevintran

14

In Ihrem Ruby on Rails-Controller können Sie Folgendes verwenden:

private

before_filter :safari_cookie_fix

def safari_cookie_fix
  user_agent = UserAgent.parse(request.user_agent) # Uses useragent gem!
  if user_agent.browser == 'Safari' # we apply the fix..
    return if session[:safari_cookie_fixed] # it is already fixed.. continue
    if params[:safari_cookie_fix].present? # we should be top window and able to set cookies.. so fix the issue :)
      session[:safari_cookie_fixed] = true
      redirect_to params[:return_to]
    else
      # Redirect the top frame to your server..
      render :text => "<script>alert('start redirect');top.window.location='?safari_cookie_fix=true&return_to=#{set_your_return_url}';</script>"
    end
  end
end

Gibt es ein ähnliches Problem bei Sitzungen auf Safari?
Rails Anfänger

Sie können set_your_return_url durch request.env ['HTTP_REFERER'] ersetzen, da wir uns in einem Iframe befinden :-D
Luc Boissaye

Ich habe diese Lösung ausprobiert und das einzige Problem ist, dass ich nicht zur übergeordneten Iframe-URL zurückkehren kann. Gibt es in Rails eine Methode, um die URL des übergeordneten Iframes abzurufen? danke
idejuan

Es hat einige Zeit gedauert, aber schließlich habe ich herausgefunden, dass der einfachste Weg (TMO) darin besteht, es einfach als Abfragezeichenfolgenparameter zur Umleitungs-URL der Rails-App hinzuzufügen. Wasy und sauber.
Guyaloni

1
Diese Antwort erstellt einen offenen Redirector, was ein häufiges Sicherheitsproblem darstellt. Der gefährliche Code ist redirect_to params[:return_to]. Dieser Parameter muss mit einer Whitelist sicherer Orte verglichen werden, an die umgeleitet werden kann. Siehe owasp.org/index.php/…
Phylae

13

Für meine spezielle Situation habe ich das Problem gelöst, indem ich window.postMessage () verwendet und jegliche Benutzerinteraktion eliminiert habe. Beachten Sie, dass dies nur funktioniert, wenn Sie js im übergeordneten Fenster ausführen können. Entweder indem Sie ein js aus Ihrer Domain einfügen oder wenn Sie direkten Zugriff auf die Quelle haben.

Im iframe (domain-b) überprüfe ich, ob ein Cookie vorhanden ist, und wenn es nicht gesetzt ist, wird eine postMessage an das übergeordnete Element (domain-a) gesendet. Z.B;

if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1
    && document.cookie.indexOf("safari_cookie_fix") < 0) {
    window.parent.postMessage(JSON.stringify({ event: "safariCookieFix", data: {} }));
}

Warten Sie dann im übergeordneten Fenster (Domäne-a) auf das Ereignis.

if (typeof window.addEventListener !== "undefined") {
    window.addEventListener("message", messageReceived, false);
}

function messageReceived (e) {
    var data;

    if (e.origin !== "http://www.domain-b.com") {
        return;
    }

    try {
        data = JSON.parse(e.data);
    }
    catch (err) {
        return;
    }

    if (typeof data !== "object" || typeof data.event !== "string" || typeof data.data === "undefined") {
        return;
    }

    if (data.event === "safariCookieFix") {
        window.location.href = e.origin + "/safari/cookiefix"; // Or whatever your url is
        return;
    }
}

Schließlich setzen Sie auf Ihrem Server (http://www.domain-b.com/safari/cookiefix) das Cookie und leiten es zurück zu dem Ort, von dem der Benutzer gekommen ist. Das folgende Beispiel verwendet ASP.NET MVC

public class SafariController : Controller
{
    [HttpGet]
    public ActionResult CookieFix()
    {
        Response.Cookies.Add(new HttpCookie("safari_cookie_fix", "1"));

        return Redirect(Request.UrlReferrer != null ? Request.UrlReferrer.OriginalString : "http://www.domain-a.com/");
    }

}

Bei Ihrem Aufruf von postMessage wird kein Syntaxfehler angezeigt?
Akousmata

Brauchen Sie noch einen zweiten Parameter hinzuzufügen , "*"um PostMessageden Syntaxfehler zu beheben
Michael Baldry

Ich wünschte, ich könnte dieser Antwort mehr positive Stimmen geben. Dies ist der einfachste und korrekteste Weg, um dieses Problem tatsächlich anzugehen. Vielen Dank für die Veröffentlichung!
AaronP

9

Ich hatte das gleiche Problem und heute habe ich eine Lösung gefunden, die für mich gut funktioniert. Wenn der Benutzeragent enthält Safariund keine Cookies gesetzt sind, leite ich den Benutzer zum OAuth-Dialog um:

<?php if ( ! count($_COOKIE) > 0 && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')) { ?>
<script type="text/javascript">
    window.top.location.href = 'https://www.facebook.com/dialog/oauth/?client_id=APP_ID&redirect_uri=MY_TAB_URL&scope=SCOPE';
</script>
<?php } ?>

Nach der Authentifizierung und dem Anfordern von Berechtigungen wird der OAuth-Dialog zu meiner URI an der obersten Position umgeleitet. Das Setzen von Cookies ist also möglich. Für alle unsere Canvas- und Page-Tab-Apps habe ich bereits das folgende Skript eingefügt:

<script type="text/javascript">
    if (top.location.href==location.href) top.location.href = 'MY_TAB_URL';
</script>

Daher wird der Benutzer mit einem bereits gesetzten gültigen Cookie erneut auf die Registerkarte der Facebook-Seite weitergeleitet und die signierte Anfrage wird erneut veröffentlicht.


Tolle Arbeit daran. Ich habe die Überprüfung des Benutzeragenten aktualisiert, um sicherzustellen, dass Chrome nicht auch im Benutzeragenten enthalten ist, da Chrome auch Safari in der Zeichenfolge des Benutzeragenten enthält. Das Umleiten auf die Seite Ihrer Domain, das Setzen der erforderlichen Cookies / das Starten der Sitzung und das anschließende Weiterleiten zu Ihrer App auf apps.facebook.com funktionierte wie ein Zauber. Scheint albern, funktioniert aber gut. Danke Sascha für den Tipp!
Mike

7

Ich habe mich schließlich für eine ähnliche Lösung entschieden wie Sascha, allerdings mit einigen Anpassungen, da ich die Cookies explizit in PHP setze:

// excecute this code if user has not authorized the application yet
// $facebook object must have been created before

$accessToken = $_COOKIE['access_token']

if ( empty($accessToken) && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') ) {

    $accessToken = $facebook->getAccessToken();
    $redirectUri = 'https://URL_WHERE_APP_IS_LOCATED?access_token=' . $accessToken;

} else {

    $redirectUri = 'https://apps.facebook.com/APP_NAMESPACE/';

}

// generate link to auth dialog
$linkToOauthDialog = $facebook->getLoginUrl(
    array(
        'scope'         =>  SCOPE_PARAMS,
        'redirect_uri'  =>  $redirectUri
    )
);

echo '<script>window.top.location.href="' . $linkToOauthDialog . '";</script>';

Dadurch wird überprüft, ob das Cookie verfügbar ist, wenn der Browser Safari ist. Im nächsten Schritt befinden wir uns in der Anwendungsdomäne, nämlich der oben als URL_WHERE_APP_IS_LOCATED angegebenen URI.

if (isset($_GET['accessToken'])) {

    // cookie has a lifetime of only 10 seconds, so that after
    // authorization it will disappear
    setcookie("access_token", $_GET['accessToken'], 10); 

} else {

  // depending on your application specific requirements
  // redirect, call or execute authorization code again
  // with the cookie now set, this should return FB Graph results

}

Nach der Umleitung in die Anwendungsdomäne wird explizit ein Cookie gesetzt, und ich leite den Benutzer zum Autorisierungsprozess weiter.

In meinem Fall (da ich CakePHP verwende, es aber mit jedem anderen MVC-Framework problemlos funktionieren sollte) rufe ich die Anmeldeaktion erneut auf, wenn die FB-Autorisierung ein anderes Mal ausgeführt wird, und diesmal ist sie aufgrund des vorhandenen Cookies erfolgreich.

Nachdem ich die App einmal autorisiert hatte, hatte ich keine Probleme mehr mit der App mit Safari (5.1.6).

Hoffe das könnte jemandem helfen.


1
das hat bei mir funktioniert !! Vielen Dank!! .. ich hatte dieses Problem mit Safari 5.1.7 .... jetzt ist es gelöst!
Khalizar

5

Ich hatte dieses Problem auf Geräten mit iOS. Ich habe mit einem Iframe einen Shop erstellt, der in eine normale Website eingebettet werden kann. Irgendwie erhielt der Benutzer bei jedem Seitenladen eine neue Sitzungs-ID, was dazu führte, dass Benutzer in der Mitte des Prozesses stecken blieben, weil einige Werte in der Sitzung nicht vorhanden waren.

Ich habe einige der auf dieser Seite angegebenen Lösungen ausprobiert, aber Popups funktionieren auf einem iPad nicht sehr gut und ich brauchte die transparenteste Lösung.

Ich habe es mit einer Umleitung gelöst. Die Website, auf der meine Website eingebettet ist, muss den Benutzer zuerst auf meine Website umleiten. Der obere Frame enthält also die URL zu meiner Website, auf der ich ein Cookie setze und den Benutzer auf die richtige Seite auf der Website umführe, auf der meine Website eingebettet ist, die übergeben wird durch in der URL.

Beispiel PHP-Code

Die Remote-Website leitet den Benutzer an weiter

http://clientname.example.com/init.php?redir=http://www.domain.com/shop/frame

init.php

<?php
// set a cookie for a year
setcookie('initialized','1',time() + 3600 * 24 * 365, '/', '.domain.com', false, false);
header('location: ' . $_GET['redir']);
die;

Der Benutzer landet dort, http://www.domain.com/shop/framewo meine Website eingebettet ist, speichert Sitzungen wie gewünscht und isst Cookies.

Hoffe das hilft jemandem.


3

Lassen Sie mich meinen Fix in ASP.NET MVC 4 teilen. Die Hauptidee wie in der richtigen Antwort für PHP. Der nächste Code, der im Hauptlayout in der Kopfzeile neben den Skripten hinzugefügt wurde:

@if (Request.Browser.Browser=="Safari")
{
    string pageUrl = Request.Url.GetLeftPart(UriPartial.Path);
    if (Request.Params["safarifix"] != null && Request.Params["safarifix"] == "doSafariFix")
    {
        Session["IsActiveSession"] = true;
        Response.Redirect(pageUrl);
        Response.End();
    }
        else if(Session["IsActiveSession"]==null)
    {
        <script>top.window.location = "?safarifix=doSafariFix";</script>
    }
}

3

Diese Lösung gilt in einigen Fällen - wenn möglich:

Wenn die Iframe-Inhaltsseite eine Subdomain der Seite verwendet, die den Iframe enthält, wird das Cookie nicht mehr blockiert.


Dies sind nützliche Informationen - genau das, wonach ich gesucht habe. Ich bin mir zwar sicher, dass die meisten Leute die Domains nicht wechseln können, aber das werde ich tun. Lassen Sie die Site, in die ich einbette, eine <mycompany>. <theircompany> .com-Subdomain erstellen, die meiner IP und einem VHost auf meiner Seite für diese Domain zugeordnet ist, und verwenden Sie diese URL im iFrame. Kompliziert, sollte aber kugelsicher sein.
Elocution Safari

1
Dies kann kompliziert werden, wenn Sie https mit der Subdomain verwenden, da der Subdomain-Server ein entsprechendes SSL-Zertifikat benötigt.
Roger Halliburton

1

Google hat die Katze tatsächlich aus der Tasche gelassen. Sie benutzten es für eine Weile, um auf Tracking-Cookies zuzugreifen. Es wurde fast sofort von Apple = \ behoben

Originaler Beitrag im Wall Street Journal


Ich weiß über die Google-Sache Bescheid, aber ich habe nichts darüber gesehen, dass Apple dies tatsächlich „repariert“ (und das halbe Internet kaputt macht). Hast du irgendwelche Details dazu?
Mscha

1

Hier ist ein Code, den ich benutze. Ich habe festgestellt, dass Cookies von nun an auf magische Weise im Iframe funktionieren, wenn ich Cookies von meiner Website setze.

http://developsocialapps.com/foundations-of-a-facebook-app-framework/

 if (isset($_GET['setdefaultcookie'])) {
        // top level page, set default cookie then redirect back to canvas page
        setcookie ('default',"1",0,"/");
        $url = substr($_SERVER['REQUEST_URI'],strrpos($_SERVER['REQUEST_URI'],"/")+1);
        $url = str_replace("setdefaultcookie","defaultcookieset",$url);
        $url = $facebookapp->getCanvasUrl($url);
        echo "<html>\n<body>\n<script>\ntop.location.href='".$url."';\n</script></body></html>";
        exit();
    } else if ((!isset($_COOKIE['default'])) && (!isset($_GET['defaultcookieset']))) {
        // no default cookie, so we need to redirect to top level and set
        $url = $_SERVER['REQUEST_URI'];
        if (strpos($url,"?") === false) $url .= "?";
        else $url .= "&";
        $url .= "setdefaultcookie=1";
        echo "<html>\n<body>\n<script>\ntop.location.href='".$url."';\n</script></body></html>";
        exit();
    }

1

Eine etwas einfachere Version in PHP von dem, was andere gepostet haben:

if (!isset($_COOKIE, $_COOKIE['PHPSESSID'])) {
    print '<script>top.window.location="https://example.com/?start_session=true";</script>';
    exit();
}

if (isset($_GET['start_session'])) {
    header("Location: https://apps.facebook.com/YOUR_APP_ID/");
    exit();
}

1

Ich habe die perfekte Antwort darauf gefunden, alles dank eines Mannes namens Allan, der hier alle Ehre verdient. ( http://www.allannienhuis.com/archives/2013/11/03/blocked-3rd-party-session-cookies-in-iframes/ )

Seine Lösung ist einfach und leicht zu verstehen.

Fügen Sie auf dem iframe-Inhaltsserver (Domäne 2) auf der Ebene der Stammdomäne eine Datei mit dem Namen Startsession.php hinzu, die Folgendes enthält:

<?php
// startsession.php
session_start();
$_SESSION['ensure_session'] = true;
die(header('location: '.$_GET['return']));

Auf der Website der obersten Ebene, die den Iframe (Domäne1) enthält, sollte der Aufruf der Seite mit dem Iframe folgendermaßen aussehen:

<a href="https://domain2/startsession.php?return=http://domain1/pageWithiFrame.html">page with iFrame</a>

Und das ist es! Simples :)

Der Grund dafür ist, dass Sie den Browser an eine URL eines Drittanbieters weiterleiten und ihn daher anweisen, ihm zu vertrauen, bevor Sie Inhalte aus ihm im iframe anzeigen.


0

Ich habe den modifizierten Whiteagle-Trick verwendet (dem Sign einen signierten_Anforderungsparameter hinzugefügt) und er hat für Safari funktioniert, aber der IE aktualisiert die Seite in diesem Fall ständig. Meine Lösung für Safari und Internet Explorer lautet also:

$fbapplink = 'https://apps.facebook.com/[appnamespace]/';
$isms = stripos($_SERVER['HTTP_USER_AGENT'], 'msie') !== false;

// safari fix
if(! $isms  && !isset($_SESSION['signed_request'])) {

    if (isset($_GET["start_session"])) {
        $_SESSION['signed_request'] = $_GET['signed_request'];
        die(header("Location:" . $fbapplink ));

    }
    if (!isset($_GET["sid"])) {
        die(header("Location:?sid=" . session_id() . '&signed_request='.$_REQUEST['signed_request']));
    }
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid) {
    ?>
    <script>
        top.window.location="?start_session=true";
    </script>
    <?php
    exit;
    }
}

// IE fix
header('P3P: CP="CAO PSA OUR"');
header('P3P: CP="HONK"');


.. later in the code

$sr = $_REQUEST['signed_request'];
if($sr) {
        $_SESSION['signed_request'] = $sr;
} else {
        $sr = $_SESSION['signed_request'];
}

0

Ich habe auch unter diesem Problem gelitten, aber endlich die Lösung gefunden. Zunächst direkt das Laden der Iframe-URL in den Browser wie ein kleines Popup, dann nur auf die Sitzungswerte innerhalb des Iframes zugreifen.



-2

Ich beschloss, die $_SESSIONVariable alle zusammen loszuwerden und schrieb einen Wrapper um Memcache, um die Sitzung nachzuahmen.

Überprüfen Sie https://github.com/manpreetssethi/utils/blob/master/Session_manager.php

Anwendungsfall: Sobald ein Benutzer in der App landet, speichern Sie die signierte Anforderung mit dem Session_manager. Da sie sich im Cache befindet, können Sie von nun an auf jeder Seite darauf zugreifen.

Hinweis: Dies funktioniert nicht, wenn Sie privat in Safari surfen, da die Sitzungs-ID jedes Mal zurückgesetzt wird, wenn die Seite neu geladen wird. (Dumme Safari)


-9

Sie können dieses Problem beheben, indem Sie den Header als p3p-Richtlinie hinzufügen. Ich hatte das gleiche Problem auf Safari. Nachdem Sie den Header über den Dateien hinzugefügt haben, ist mein Problem behoben.

<?php
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
?>

Sind Sie sicher, dass dies (noch) mit der neuesten Version von Safari funktioniert? Wir haben seit Jahren P3P-Header für IE, aber Safari ist immer noch kaputt.
Mscha

2
Löschen Sie alle Cookies und testen Sie sie erneut. Das Problem tritt nicht auf, wenn Ihr Browser bereits Cookies für Ihre iframed-Site enthält.
Rmarscher

Hmmm, ich kann die P3P-Header auch nicht zum Laufen bringen. Sie arbeiten aber immer noch im IE!
Seth Brown

2
Das hat früher funktioniert. Bei der neuesten Version von Safari ist dies jedoch nicht der Fall.
Leeren

2
Ich möchte feststellen, dass diese Lösung funktioniert. Stellen Sie sicher, dass Sie alle Cookies auf Safari löschen. Und dann versuchen Sie es.
dnuske
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.