2009-05-07 13 views
13

Ho un'applicazione iframe di Facebook completamente esterna. Con questo intendo che una volta che un utente accede all'URL del canvas per caricare l'applicazione, tutti i link nell'app iframe vanno ai miei server, e la pagina canvas non viene mai aggiornata a meno che l'utente non naviga da qualche altra parte su Facebook e ritorni (o aggiorna un browser).Aggiornamento sessione Facebook da un'applicazione iframe

Sul caricamento iniziale dell'app in cui Facebook crea l'iframe, ho superato tutti i parametri usuali come fb_sig_user che mi consente di creare una sessione di app interna basata sull'utente di Facebook. Questa sessione dell'app (che è non la sessione di Facebook, è la mia sessione app) è tutto ciò di cui ho bisogno per consentire all'utente di lavorare con l'app.

Il problema arriva un'ora più tardi. Se l'utente lascia il computer o utilizza l'app per più di un'ora, la sessione di Facebook scade. Esistono alcune pagine di app che richiedono il recupero di informazioni sugli amici e, una volta scaduta la sessione FB, queste pagine si interrompono, generando errori come "Errore: chiave di sessione non valida o non più valida".

La mia domanda è se esiste un modo per aggiornare la sessione di Facebook dell'utente all'interno di un'applicazione iframe per impedire che scada un'ora dopo. Qualcuno delle chiamate API fa questo? C'è un trucco di Facebook Connect per eseguire il ping qualcosa? C'è qualche metodo definitivo per tenerlo in vita? Non sono stato in grado di trovare esempi che lo riguardino in modo specifico.

risposta

21

La vittoria è mia!

C'è una funzione di Facebook quasi completamente non documentata che si occupa di sessioni di iframe, che ho trovato uno vague reference to nella mia ricerca. Questa pagina in realtà non lo spiega bene, e solo dopo diverse ore di visione di varie chiavi di sessione nel mio iframe sono riuscito a capire cosa stava succedendo.

In precedenza, la mia app iframe ha ricevuto il solito round di parametri fb_whatever quando si verificava il carico iniziale dell'iframe. Quindi, nella mia domanda, stavo facendo questo su ogni richiesta:

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']; 

Questo codice avrebbe ricevuto il fb_sig_session_key sul carico applicazione iniziale, e vorrei scoiattolo via in un locale $_SESSION per l'uso con l'API. È necessario archiviarlo nella sessione locale, perché fb_sig_session_key non viene mai passato di nuovo a meno che non si ricarica l'intero iframe dell'app.

Quindi i problemi si sono verificati quando questa chiave di sessione è scaduta un'ora dopo.

Dopo aver esaminato lo vague reference page, ho iniziato a esaminare tutte le variabili $_REQUEST che stavo ottenendo. Si scopre che anche su un link interno all'interno della tua app iframe, Facebook modifica la richiesta di passare alcuni parametri. Per qualche ragione, hanno un completamente differente, ma anche una chiave di sessione valida che arriva insieme a ogni richiesta di iframe!

Questo parametro prende il nome dalla chiave API dell'applicazione Facebook. Quindi, se la tua chiave API dell'applicazione è "xyz123", ogni richiesta all'interno dell'iframe riceve un parametro chiamato xyz123_session_key (così come alcuni altri, come xyz123_expires e xyz123_user).

Dopo aver visto il tempo di scadenza associata per la sessione principale (l'originale fb_sig_session_key) e questa sessione iframe-only (xyz123_session_key), la luce alla fine del tunnel è apparso: la chiave di sessione tempo di scadenza iframe solo ottiene in realtà aggiornato occasionalmente. Non ho determinato quando o come (presumo sia un ping Ajax ad un certo punto), ma ciò nonostante, si aggiorna.

Ho aspettato la scadenza della sessione originale fb_sig_session_key e in effetti le pagine relative agli amici nella mia app hanno iniziato a provocare errori di tosse. A quel punto, ho spostato la mia chiave di sessione memorizzata localmente nel nuovo xyz123_session_key iframe e il problema è stato risolto. Quella sessione funziona altrettanto bene dell'originale!

Quindi, il mio fix codice finale è quello di memorizzare la chiave di sessione a livello locale come segue:

$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']; 

Questo dà la preferenza al tasto "iframe-only".

Modifica: La mia ipotesi originale che la chiave "iframe-only" è stata aggiornata tramite una sorta di metodo Ajax era errata, risulta che questi valori sono impostati in un cookie da Facebook. Questo porta ad alcuni problemi interdominio quando si utilizzano questi cookie. Impostando un P3P cookie policy si allevierà questo con la maggior parte dei browser, eccetto Safari. Non c'è ancora un buon lavoro in giro per Safari.

+0

Sembra che questo metodo utilizzi i cookie, quindi Safari ha qualche difficoltà con esso, in quanto i cookie sono di dominio incrociato. – zombat

+0

Bene, tramite Ajax è possibile salvare (alla prima pagina) e recuperarlo da un DB in tutte le pagine seguenti - se ottengo la soluzione giusta. Ovviamente deve essere salvato con l'ID utente fb come chiave, ma questo dovrebbe essere ancora in grado di ottenere o? A causa del problema relativo ai cookie crossdomain, sto risolvendo quasi tutto tramite un database e Ajax. In ogni caso Complimenti per le tue indagini su questo argomento, sono le informazioni che stavo cercando :-) – SamiSalami

+0

Sembra che potresti non essere più in grado di ottenere i UserId, se la sessione è scaduta, quindi potresti semplicemente usare il vecchio stile via e posta in input nascosti attraverso la tua app ... soluzione brutta di sicuro, ma dovrebbe funzionare e cercherò di andare con quella. – SamiSalami

2

Basta mettere

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

sulla parte superiore della pagina e non si perde la sessione in iframe.

Ho anche notato che questa discussione ha una buona validità di 2 anni e mezzo. Ho appena scoperto che sta usando Google. Forse il mio post aiuterà qualcun altro che si imbatte in questo.

+0

È una soluzione utilizzata solo per IE, che perde sempre la sessione FB, ma questo non ha nulla a che fare con la scadenza della sessione dopo un'ora - questo sarà sempre il caso, FB lascia scadere. Anche per risolvere il problema di IE dovresti usare questa intestazione completa: header ('P3P: CP = "IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONI IL NOSTRO IND CNT"'); – SamiSalami

Problemi correlati