2009-05-07 8 views
13

Ich habe eine Facebook-Iframe-Anwendung, die vollständig extern ist. Damit meine ich, dass sobald ein Benutzer auf die Canvas-URL zugreift, um die Anwendung zu laden, alle Links in der iframe-App auf meine Server gehen und die Canvas-Seite nie aktualisiert wird, es sei denn, der Benutzer navigiert zu einem anderen Ort auf Facebook und kommt zurück Aktualisiert einen Browser).Erfrischende Facebook-Sitzung von einer iframe-Anwendung

Beim ersten Laden der App, wo Facebook den iframe erstellt, bekomme ich alle üblichen Parameter wie fb_sig_user übergeben, was mir erlaubt, eine interne App-Sitzung basierend auf dem Facebook-Benutzer zu erstellen. Diese App-Sitzung (das ist nicht die Facebook-Sitzung, es ist meine eigene App-Sitzung) ist alles, was ich brauche, um den Benutzer mit der App arbeiten zu lassen.

Das Problem kommt eine Stunde später. Wenn der Benutzer den Computer verlässt oder die App länger als eine Stunde verwendet, verfällt die Facebook-Sitzung. Es gibt einige App-Seiten, auf denen Freundschaftsinformationen abgerufen werden müssen. Sobald die FB-Sitzung abgelaufen ist, werden diese Seiten unterbrochen und Fehler wie "Fehler: Sitzungsschlüssel ungültig oder nicht mehr gültig" werden ausgegeben.

Meine Frage ist, ob es eine Möglichkeit gibt, die Facebook-Sitzung des Benutzers aus einer Iframe-Anwendung zu aktualisieren, damit sie eine Stunde später nicht abläuft. Führt einer der API-Aufrufe dazu? Gibt es einen Facebook Connect-Trick, um etwas zu pingen? Gibt es eine definitive Methode, um sie am Leben zu erhalten? Ich bin nicht in der Lage gewesen, Beispiele zu finden, die speziell darauf eingehen.

Antwort

21

Der Sieg gehört mir!

Es gibt eine fast vollständig undokumentierte Facebook-Funktion, die sich mit Iframe-Sitzungen beschäftigt, die ich in meinen Recherchen auf vague reference to gefunden habe. Diese Seite erklärt es aber nicht wirklich, und erst nach einigen Stunden der Beobachtung verschiedener Sitzungsschlüssel in meinem iframe konnte ich herausfinden, was vor sich ging.

Zuvor erhielt meine iframe-App die übliche Runde von fb_whatever-Parametern, als die anfängliche iframe-Last auftrat. Also in meiner Anwendung, tat ich dies bei jeder Anfrage:

if (isset($_REQUEST['fb_sig_session_key'])) { 
    $_SESSION['fb_sig_session_key'] = $_REQUEST['fb_sig_session_key']; 
} 
if (! empty($_SESSION['fb_sig_session_key'])) $this->facebook->api_client->session_key = $_SESSION['fb_sig_session_key']; 

Dieser Code würde die fb_sig_session_key auf der anfänglichen app Last empfängt, und ich würde es weg in eine lokalen $_SESSION zur Verwendung mit dem API Eichhörnchen. Das Speichern in der lokalen Sitzung ist erforderlich, da fb_sig_session_key niemals erneut übergeben wird, es sei denn, Sie laden den gesamten App-iFrame neu.

Die Probleme traten auf, wenn dieser Sitzungsschlüssel etwa eine Stunde später ablief.

Nach dem Blick auf die vague reference page, fing ich an, alle $_REQUEST Variablen zu untersuchen, die ich bekam. Es stellt sich heraus, dass Facebook selbst bei einem internen Link in Ihrer iframe-App die Anfrage ändert, einige Parameter weiterzugeben. Aus irgendeinem Grund haben sie einen völlig unterschiedlichen, aber auch gültigen Sitzungsschlüssel, der mit jeder iframe-Anforderung einhergeht!

Dieser Parameter ist nach Ihrem Facebook-API-API-Schlüssel benannt. Wenn also Ihr Anwendungs-API-Schlüssel "xyz123" ist, erhält jede Anfrage in Ihrem iframe einen Parameter mit dem Namen xyz123_session_key (sowie einige andere, wie xyz123_expires und xyz123_user).

Nach der zugehörigen Ablaufzeit für die Hauptsitzung zu beobachten (das Original fb_sig_session_key) und diese iframe-only-Sitzung (xyz123_session_key), das Licht am Ende des Tunnels erschien: die iframe-only tatsächlich Ablaufzeit Sitzungsschlüssel wird gelegentlich aktualisiert. Ich habe nicht festgestellt, wann oder wie (ich nehme an, es ist ein Ajax-Ping zu einem bestimmten Zeitpunkt), aber dennoch, es aktualisiert.

Ich wartete auf die ursprüngliche fb_sig_session_key Sitzung ablaufen, und sicher genug die Freunde-Seiten in meiner App husten Fehler. An diesem Punkt wechselte ich meinen lokal gespeicherten Sitzungsschlüssel zu dem neuen iframe-only xyz123_session_key, und das Problem wurde behoben. Diese Sitzung funktioniert genauso gut wie das Original!

Also, meine letzte Code fix ist der Sitzungsschlüssel lokal zu speichern, wie folgt:

$iframeSessionKeyName = $CONFIG['facebook']['apiKey'] . '_session_key'; 
if (isset($_REQUEST[$iframeSessionKeyName])) { 
    $_SESSION['fb_sig_session_key'] = $_REQUEST[$iframeSessionKeyName]; 
} 
else if (isset($_REQUEST['fb_sig_session_key'])) { 
    $_SESSION['fb_sig_session_key'] = $_REQUEST['fb_sig_session_key']; 
} 
if (! empty($_SESSION['fb_sig_session_key'])) $this->facebook->api_client->session_key = $_SESSION['fb_sig_session_key']; 

Dies gibt den Vorzug der "iframe-only" -Taste.

Edit: Meine ursprüngliche Annahme, dass der "iframe-only" -Schlüssel über eine Art von Ajax-Methode aktualisiert wurde, war falsch, es stellt sich heraus, dass diese Werte von Facebook in einen Cookie gesetzt werden. Dies führt bei Verwendung dieser Cookies zu einigen domänenübergreifenden Problemen. Das Einstellen eines P3P cookie policy wird dies mit den meisten Browsern, außer Safari, erleichtern. Es gibt immer noch keine gute Arbeit für Safari.

+0

Es sieht so aus, als ob diese Methode Cookies verwendet, daher hat Safari einige Schwierigkeiten damit, da die Cookies domänenübergreifend sind. – zombat

+0

Nun, über Ajax können Sie auf allen folgenden Seiten nur speichern (auf der ersten Seite) und aus einer DB abrufen - wenn ich Ihre Lösung richtig verstanden habe. Natürlich muss es mit der fb user id als Schlüssel gespeichert werden, aber das soll doch noch gehen oder? Aufgrund des Crossdomain-Cookie-Problems löse ich fast alles über eine Datenbank und Ajax. Anyways Daumen hoch für Ihre Untersuchung in dieser Angelegenheit, es ist die Informationen, die ich gesucht habe :-) – SamiSalami

+0

Es scheint, dass Sie nicht in der Lage sein, die userId mehr zu bekommen, wenn die Sitzung abgelaufen ist, so vielleicht könnten Sie nur die altmodische verwenden Weg und post in versteckten Eingaben durch Ihre App ... hässliche Lösung sicher, aber sollte funktionieren und ich werde versuchen, mit diesem zu gehen. – SamiSalami

2

Einfach

header('P3P: CP="CAO PSA OUR"'); 

oben auf Ihrer Seite und Sie werden Ihre Sitzung in der iframe nicht verlieren.

Ich habe auch bemerkt, dass dieser Thread ist gut 2 und ein halbes Jahr alt. Ich bin gerade auf Google gestoßen. Vielleicht hilft mein Beitrag einem anderen, der darauf stößt.

+0

Es ist eine Lösung nur für IE verwendet, die immer die FB-Sitzung verliert, aber das hat nichts mit dem Ablauf der Sitzung nach einer Stunde zu tun - das wird immer der Fall sein, FB lässt es ablaufen. Um das IE-Problem zu lösen, sollten Sie auch diesen vollständigen Header verwenden: header ('P3P: CP = "IDC DSP COR ADM DEVI TAI PSA PSD IVAi IVDi CONi SEIN UNSER IND CNT"'); – SamiSalami

Verwandte Themen