2009-05-07 18 views
13

Tengo una aplicación de iframe de Facebook que es completamente externa. Con esto quiero decir que una vez que un usuario accede al canvas URL para cargar la aplicación, todos los enlaces en la aplicación iframe van a mis servidores, y la página de canvas nunca se actualiza a menos que el usuario navegue a otro lugar en Facebook y regrese (o se actualiza el navegador).Refrescante sesión de Facebook desde una aplicación de iframe

En la carga inicial de la aplicación donde Facebook crea el iframe, me pasan todos los parámetros habituales como fb_sig_user que me permite crear una sesión de aplicación interna basada en el usuario de Facebook. Esta sesión de aplicación (que es no la sesión de Facebook, es mi propia sesión de aplicación) es todo lo que necesito para permitir que el usuario trabaje con la aplicación.

El problema llega una hora más tarde. Si el usuario abandona la computadora o usa la aplicación durante más de una hora, la sesión de Facebook caducará. Hay algunas páginas de aplicaciones que requieren recuperar información de amigos, y una vez que la sesión de FB expiró, estas páginas se rompen, arrojando errores como "Error: la clave de sesión no es válida o ya no es válida".

Mi pregunta es si hay una manera de actualizar la sesión de Facebook del usuario desde dentro de una aplicación iframe para evitar que caduque una hora más tarde. ¿Alguna de las llamadas API hace esto? ¿Hay un truco de Facebook Connect para hacer ping a algo? ¿Hay algún método definitivo para mantenerlo vivo? No he podido encontrar ningún ejemplo que aborde específicamente esto.

Respuesta

21

¡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.

+0

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

+0

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

+0

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

2

sólo hay que poner

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

en la parte superior de la página y que no perderá su sesión en el iframe.

También noté que este hilo tiene una antigüedad de 2 años y medio. Me encontré con Google. Tal vez mi publicación ayudará a alguien más que se encuentre con esto.

+0

Es una solución que solo se usa para IE, que siempre pierde la sesión de FB, pero esto no tiene nada que ver con la expiración de la sesión después de una hora; este siempre es el caso, FB expira. También para resolver el problema de IE, debe usar este encabezado completo: header ('P3P: CP = "IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONI NUESTRO IND CNT"'); – SamiSalami

Cuestiones relacionadas