13 Stimmen

Aktualisieren der Facebook-Sitzung aus einer Iframe-Anwendung

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 zu meinen Servern gehen, und die Canvas-Seite wird nie aktualisiert, es sei denn, der Benutzer navigiert zu einem anderen Ort auf Facebook und kommt zurück (oder tut eine Browser-Aktualisierung).

Beim anfänglichen Laden der App, bei dem Facebook den iframe erstellt, werden mir alle üblichen Parameter wie fb_sig_user übergeben, die es mir ermöglichen, eine interne App-Sitzung auf der Grundlage des Facebook-Benutzers zu erstellen. Diese App-Sitzung (die no die Facebook-Sitzung, es ist meine eigene App-Sitzung) ist alles, was ich brauche, damit der Benutzer mit der App arbeiten kann.

Das Problem kommt eine Stunde später. Wenn der Benutzer den Computer verlässt oder die App länger als eine Stunde verwendet, läuft die Facebook-Sitzung ab. Es gibt einige App-Seiten, die das Abrufen von Freundesinformationen erfordern, und sobald die FB-Sitzung abgelaufen ist, brechen diese Seiten ab und geben Fehler aus wie "Fehler: Sitzungsschlüssel ungültig oder nicht mehr gültig".

Meine Frage ist, ob es eine Möglichkeit gibt, die Facebook-Sitzung des Benutzers innerhalb einer Iframe-Anwendung zu aktualisieren, damit sie nicht eine Stunde später abläuft. Kann einer der API-Aufrufe dies tun? Gibt es einen Facebook Connect-Trick, um etwas anzupingen? Gibt es eine definitive Methode, um die Sitzung aufrechtzuerhalten? Ich habe keine Beispiele gefunden, die speziell auf dieses Problem eingehen.

21voto

zombat Punkte 89911

Der Sieg ist mein!

Es gibt eine fast gänzlich undokumentierte Facebook-Funktion, die sich mit iframe-Sitzungen befasst, und ich fand eine vager Hinweis auf in meiner Forschung. Diese Seite erklärt es jedoch nicht wirklich gut, und erst nach mehreren Stunden, in denen ich verschiedene Sitzungsschlüssel in meinem iframe beobachtet habe, konnte ich herausfinden, was vor sich ging.

Zuvor erhielt meine iframe-Anwendung die übliche Runde von fb_whatever Parameter, wenn der iframe zum ersten Mal geladen wurde. In meiner Anwendung habe ich dies also bei jeder Anfrage getan:

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 beim anfänglichen Laden der App, und ich würde sie in eine lokale $_SESSION zur Verwendung mit der API. Die Speicherung in der lokalen Sitzung ist notwendig, weil fb_sig_session_key wird nie wieder übergeben, es sei denn, Sie laden die gesamte App iframe neu.

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

Nach einem Blick auf die vage Referenzseite habe ich angefangen, alle diese Dinge zu untersuchen. $_REQUEST Variablen, die ich erhielt. Es hat sich herausgestellt, dass Facebook selbst bei einem internen Link innerhalb Ihrer iframe-App die Anfrage ändert, um einige Parameter weiterzugeben. Aus irgendeinem Grund haben sie eine völlig anders, aber auch gültig Sitzungsschlüssel, der mit jeder iframe-Anfrage einhergeht!

Dieser Parameter ist nach dem Schlüssel Ihrer Facebook-Anwendung benannt. Wenn Ihr Anwendungs-API-Schlüssel also "xyz123" lautet, erhält jede Anfrage innerhalb Ihres iframe einen Parameter namens xyz123_session_key (sowie ein paar andere, wie xyz123_expires y xyz123_user ).

Nachdem Sie die zugehörige Ablaufzeit für die Hauptsitzung (die ursprüngliche fb_sig_session_key ) und diese iframe-only-Sitzung ( xyz123_session_key ), erschien das Licht am Ende des Tunnels: die Ablaufzeit des iframe-only Sitzungsschlüssels wird tatsächlich gelegentlich aktualisiert . Ich habe nicht herausgefunden, wann oder wie (ich nehme an, es ist ein Ajax-Ping zu einem bestimmten Zeitpunkt), aber nichtsdestotrotz, es wird aktualisiert.

Ich habe auf das Original gewartet fb_sig_session_key Sitzung ablaufen lassen, und tatsächlich begannen die befreundeten Seiten in meiner App, Fehler zu melden. An diesem Punkt wechselte ich meinen lokal gespeicherten Sitzungsschlüssel auf den neuen iframe-only xyz123_session_key und das Problem war gelöst. Diese Sitzung funktioniert genauso gut wie das Original!

Mein endgültiger Code besteht also darin, den Sitzungsschlüssel wie folgt lokal zu speichern:

$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 dem Schlüssel "Nur Rahmen" den Vorzug.

Editar: Meine ursprüngliche Annahme, dass der "iframe-only"-Schlüssel über eine Art Ajax-Methode aktualisiert wird, war falsch. Es stellte sich heraus, dass diese Werte von Facebook in einem Cookie gespeichert werden. Dies führt zu einigen domänenübergreifenden Problemen bei der Verwendung dieser Cookies. Das Setzen eines P3P-Cookie-Richtlinie wird dieses Problem bei den meisten Browsern außer Safari beheben. Für Safari gibt es noch keine gute Lösung.

0 Stimmen

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

0 Stimmen

Nun, über Ajax könnten Sie einfach speichern (auf der ersten Seite) und es von einer DB auf allen folgenden Seiten abrufen - wenn ich Ihre Lösung richtig verstehe. Natürlich muss es mit der fb user id als Schlüssel gespeichert werden, aber das sollte doch möglich sein, oder? Wegen der Crossdomain-Cookie-Problematik löse ich fast alles über eine Datenbank und Ajax. Auf jeden Fall Daumen hoch für Ihre Untersuchung in dieser Angelegenheit, es ist die Information, die ich gesucht habe :-)

0 Stimmen

Es scheint, dass Sie möglicherweise nicht in der Lage, die userId mehr zu erhalten, wenn die Sitzung abgelaufen ist, so vielleicht Sie nur die altmodische Art und Weise und Post in versteckten Eingaben durch Ihre App verwenden könnte... hässliche Lösung für sicher, aber sollte funktionieren und ich werde versuchen, mit dieser einen zu gehen.

2voto

Jan K. Punkte 1601

Setzen Sie einfach

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

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

Mir ist auch aufgefallen, dass dieser Thread schon gut zweieinhalb Jahre alt ist. Ich bin gerade über Google darüber gestolpert. Vielleicht hilft mein Beitrag jemand anderem, der darauf stößt.

0 Stimmen

Es ist eine Lösung, die nur für den IE verwendet wird, der 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 sie ablaufen. Auch um das IE-Problem zu lösen, sollten Sie diesen vollständigen Header verwenden: header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X