¡La victoria es mía!
Hay una característica de Facebook casi indocumentada que trata con sesiones iframe, que encontré un vague reference to en mi investigación. Sin embargo, esta página realmente no lo explica bien, y solo después de varias horas de ver varias claves de sesión en mi iframe pude averiguar qué estaba pasando.
Anteriormente, mi aplicación iframe recibía la ronda habitual de los parámetros fb_whatever
cuando se producía la carga del iframe inicial. Así que en mi solicitud, yo estaba haciendo esto en cada petición:
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'];
Este código recibiría el fb_sig_session_key
de la carga inicial de aplicación, y me ardilla a la basura en un local de $_SESSION
para su uso con la API. Es necesario almacenarlo en la sesión local, ya que fb_sig_session_key
nunca se pasa de nuevo a menos que recargue todo el iframe de la aplicación.
Entonces, los problemas ocurrieron cuando esta clave de sesión expiró una hora más tarde.
Después de mirar el vague reference page, comencé a examinar todas las variables $_REQUEST
que estaba obteniendo. Resulta que incluso en un enlace interno dentro de su aplicación iframe, Facebook modifica la solicitud para pasar algunos parámetros. Por alguna razón, tienen una clave de sesión completamente diferente, pero también válida que viene junto con cada solicitud de iframe.
Este parámetro lleva el nombre de la clave de la aplicación Facebook. Entonces, si la clave API de su aplicación es "xyz123", cada solicitud dentro de su iframe obtiene un parámetro llamado xyz123_session_key
(así como algunos otros, como xyz123_expires
y xyz123_user
).
Después de ver el tiempo de caducidad asociada a la sesión principal (el original fb_sig_session_key
) y esta sesión iframe solamente (xyz123_session_key
), la luz al final del túnel apareció: la clave de sesión tiempo de caducidad iframe sólo consigue realmente actualizado ocasionalmente. No he determinado cuándo ni cómo (supongo que es un ping de Ajax en algún momento), pero no obstante, se actualiza.
Esperé a que la sesión original de fb_sig_session_key
expirara, y efectivamente las páginas relacionadas con amigos en mi aplicación comenzaron a generar errores. En ese momento, cambié mi clave de sesión almacenada localmente al nuevo iframe-only xyz123_session_key
, y el problema fue resuelto. ¡Esa sesión funciona tan bien como la original!
Por lo tanto, mi solución de código final es almacenar la clave de sesión localmente como sigue:
$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'];
Esto da preferencia a la tecla de "sólo iframe".
Edit: Mi hipótesis original de que la clave "iframe-only" se actualizó mediante algún tipo de método Ajax fue incorrecta, resulta que estos valores están configurados en una cookie por Facebook. Esto lleva a algunos problemas entre dominios al usar estas cookies. Establecer un P3P cookie policy lo aliviará con la mayoría de los navegadores, excepto Safari. Todavía no hay un buen trabajo para Safari.
Parece que este método utiliza cookies, por lo que Safari tiene algunas dificultades con él, ya que las cookies son de dominio cruzado. – zombat
Bueno, a través de Ajax podría simplemente guardar (en la primera página) y recuperarlo de un DB en todas las páginas siguientes, si obtengo la solución correcta. Por supuesto, debe guardarse con la identificación de usuario de fb como clave, pero aún así debería poder obtenerse o? Debido al problema de las cookies crossdomain, estoy resolviendo casi todo a través de una base de datos y Ajax. De todos modos, tengo un buen pulgar para su investigación en este asunto, es la información que he estado buscando :-) – SamiSalami
Parece que ya no podrá obtener el userId, si la sesión ha expirado, así que tal vez podría simplemente usar el anticuado manera y publicar en entradas ocultas a través de su aplicación ... la solución fea seguramente, pero debería funcionar e intentaré ir con esa. – SamiSalami