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.