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.
Sembra che questo metodo utilizzi i cookie, quindi Safari ha qualche difficoltà con esso, in quanto i cookie sono di dominio incrociato. – zombat
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
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