2013-01-05 12 views
6

davvero strano, sembra che la sessione di Facebook è persa ($ user = 0) usando il PHP SDK (v 3.2.2). L'SDK JS deve ricaricare la mia pagina per recuperare la sessione di Facebook. Questo problema si verifica ogni tanto, a volte la sessione di Facebook è persa, a volte funziona bene.sessione di Facebook PHP SDK perso, ha bisogno di JS SDK aggiornare

session_start(); 

// Run Facebook API 
$facebook = new Facebook(array(
    'appId' => $config['facebook']['id'], 
    'secret' => $config['facebook']['secret'] 
)); 

// Fetch user 
$user = $facebook->getUser(); 
if($user) { 
    try { 
    // Just to be sure, add access token to each request 
    $user['access_token'] = $facebook->getAccessToken();  

    // Fetch user details 
    $user = $facebook->api('/me?access_token='.$user['access_token']);   
    } 
    catch (FacebookApiException $e) { 
    error_log($e); 
    $user = null; 
    } 
} 

Il problema principale è che $ utente = $ facebook-> getUser(); restituisce 0. Tuttavia, poiché l'utente è effettivamente connesso, JS SDK rileva l'evento auth.login e ricarica la pagina (un'altra cosa strana, io uso auth.login perché l'evento auth.authResponseChange continua a essere attivato ogni secondo). Ora $ utente = $ facebook-> getUser(); restituisce l'uid dell'utente.

window.fbAsyncInit = function() { 
    FB.init({ 
    appId : appId, 
    channelUrl : '//domain.com/signon/channel.php', 
    status  : true, 
    cookie  : true, 
    xfbml  : true 
    }); 
    FB.Event.subscribe('auth.login', function(response) { 
    location.reload(); 
    }); 
}; 

In Facebook Developer ho definito il Domain App (domain.com) e del sito Url (http://domain.com/). URL sito già provato con/senza barra finale, non ha risolto il problema.

Qualsiasi idea di cosa sta succedendo, perché il Facebook PHP SDK non rileva immediatamente la sessione dell'utente/continua a perdere la sessione dell'utente e ha bisogno di una ricarica? Questo problema causa davvero un UX non valido.

Grazie mille!

Robin

risposta

5

sono venuto dall'altra parte lo stesso problema ultimamente, sembra che se dopo 5 minuti o giù di lì di inattività si fa una ricarica, la sessione non persistono. A volte funziona, a volte no.

ho cercato in esso per circa l'ultima settimana, e l'unica soluzione mi veniva in mente era quello di utilizzare il JS SDK di fare una pagina di ricarica con:

FB.Event.subscribe('auth.login', function(response) { 
     window.location.reload(); 
    }); 

Ma sono d'accordo, è non è una soluzione molto elegante in termini di UX. Si dovrebbe passare il cookie param in PHP SDK, e il parametro OAuth in JS SDK, e vedere se funziona (non ha fatto per me):

$facebook = new Facebook(array(
    'appId' => $config['facebook']['id'], 
    'secret' => $config['facebook']['secret'], 
    'cookie' => true 
)); 

E

FB.init({ 
    appId : appId, 
    channelUrl : '//domain.com/signon/channel.php', 
    status  : true, 
    cookie  : true, 
    xfbml  : true, 
    oauth  : true 
    }); 

Ancora più strano, ho scaricato nuovamente lo latest PHP SDK da Github e lo ho caricato su un ambiente sandbox (Apache, PHP 5.4). Ho eseguito l'esempio (con il JS SDK) AS-IS e ha lo stesso problema!

Ora, se quanto sopra proprio non è tagliato la senape, ho alcuni ulteriori suggerimenti.

CAMBIARE LO SDK su un po '

In primo luogo, passando

$facebook->getAccessToken();

non vi farà alcun bene se $user restituisce 0. Tuttavia, dopo aver fatto un po' di scavo intorno a base_facebook.php, Ho notato che il metodo getCode() utilizza effettivamente $_REQUEST per recuperare il codice di autorizzazione dai parametri di query.

dal Manuale PHP, $ _REQUEST è

Un array associativo che di default contiene il contenuto di $ _GET, $ _POST e $ _COOKIE.

MA

è molto diverso a $ _GET, $ _ POST o $ _COOKIE.

Questo può essere un po 'un bugger a seconda della configurazione. Così, invece, trovare la funzione getCode() in base_facebook.php che assomiglia a questo:

protected function getCode() { 
if (isset($_REQUEST['code'])) { 
    if ($this->state !== null && 
      isset($_REQUEST['state']) && 
      $this->state === $_REQUEST['state']) { 

     // CSRF state has done its job, so clear it 
     $this->state = null; 
     $this->clearPersistentData('state'); 
     return $_REQUEST['code']; 
    } else { 
     self::errorLog('CSRF state token does not match one provided.'); 
     return false; 
    } 
} 

return false; 
} 

e unire la query in un nuovo array/variabile (chiamiamolo $code_array) per includere le $_GET, $_POST & $_COOKIE array utilizzando array_merge() in questo modo :

$code_array = array_merge($_GET,$_POST,$_COOKIE); 

Quello che si finisce è un array che contiene tutti i dati delle rispettive richieste. Il solo andare avanti e sostituire $_REQUEST con $code_array all'interno della funzione, cioè

\\replace $_REQUEST with $code_array; 
if (isset($code_array['code'])) { 
if ($this->state !== null && 
     isset($code_array['state']) && 
     $this->state === $code_array['state']) { //...and so on for the rest 

Questo dovrebbe fare il lavoro bene (si spera).

OPTIONAL - Estendere il tuo token di accesso a vita

Questo è opzionale, ma lo ho incluso lo stesso. La maggior parte delle nuove app avrà già token di accesso di lunga durata, ma nel caso sia possibile, è possibile utilizzare il metodo $facebook->setExtendedAccessToken(); per trasformare il token di accesso esistente.

Nota: devi chiamare $facebook->setExtendedAccessToken(); prima che realmente ottenere il vostro token di accesso con il metodo getAccessToken().

Ora, utilizzando il codice si avrà

$user = $facebook->getUser(); 
    if($user) { 
    try { 
    // Just to be sure, add access token to each request 
    $facebook->setExtendedAccessToken(); 
    $access_token = $facebook->getAccessToken(); 
    // Fetch user details 
    $user = $facebook->api('/me?access_token='.$access_token); 
    } 
//and so on.. 

CONCLUSIONE

Rottura $ _REQUEST in $ _GET, $ _ POST & $ _COOKIE (anche se include tutti e tre per impostazione predefinita) sembra assicurati di poter recuperare il cookie impostato dall'SDK (s) senza troppi problemi. Dico sembra perché diamine, non sono sicuro al 100% me stesso.

I Ho utilizzato i metodi sopra riportati per farlo funzionare nel mio caso, quindi spero di condividere alcune informazioni, poiché ho perso troppo sonno per questo problema e non sono riuscito a trovare una soluzione valida.

Spero che questo aiuti!

EDIT: Ho dimenticato di dire, cambiando la richiesta API da

$user_profile = $facebook->api('/me'); 

a

$user_profile = $facebook->api('/'.$user.'?access_token='.$access_token); 

è stato qualcosa che ho anche fatto, e ha fatto la differenza. :)

+0

chiamando '$ facebook-> setExtendedAccessToken();' ha funzionato per me, grazie. – Eldar

+0

avevo un'app con il sito ai widget root e iframe su/widgets. in aggiunta alle tue modifiche in Facebook di base, ho anche dovuto creare una nuova app per i widget iframe in/widget. ora la sessione sul dominio radice sembra andare bene. –

+0

La riprendo, le sessioni vanno bene, ma l'utente continua a restituire 0 dopo che la pagina è inattiva per alcuni minuti. –

0

Forse perché l'SDK PHP di Facebook non è ajax e stiamo utilizzando pagine PHP ei nostri server caricano più velocemente del processo di autenticazione da Facebook per rileggere una sessione valida. ciò che richiede l'SDK PHP di Facebook è qualcosa per aggiornare la pagina sulla convalida della sessione dalle nostre app, questo dovrebbe essere integrato nell'SDK di Facebook, ma sembra che non lo sia.