it-swarm.com.de

Wie man Session und Zugriffstoken mit Facebook richtig handhabt PHP SDK 3.0?

Im PHP 3.0 SDK ist keine getSession() oder Sitzungsverwaltung außerhalb der Facebook-API verfügbar. Vor einigen Tagen haben die Entwickler von Facebook auch irgendwie die JavaScript-SDK aktualisiert, laut diesem Blogeintrag und diesem Fehlerbericht.

Innerhalb der letzten Tage erfolgte eine Änderung in das gehostete JS SDK eingeführt was alle Kompatibilität zwischen ihm gebrochen hat und das aktuelle PHP SDK (2.x und 3.x) . Entwickler, die sowohl JS als auch .__ verwenden. PHP SDK auf ihren Websites ist wahrscheinlich um serverseitige API-Fehler anzuzeigen.

Ich weiß jedoch nicht, ob das mein Problem wirklich beeinflusst. Wie in Antwort dieser Frage Ich rufe das Zugriffstoken des OAuth-Dialogs mit PHP ab und speichere das neue Zugriffstoken in der Sitzung.

Aktuelle Problemumgehung

Der folgende Code zeigt, wie ich mit diesen Sitzungen umgehe. $_REQUEST['session'] ist der Inhalt der Antwort des OAuth-Dialogs.

if(isset($_REQUEST['session'])) {

    $response = json_decode(stripslashes($_REQUEST['session']), true);

    if(isset($response['access_token'])) {
        $this->api->setAccessToken($response['access_token']);
        $_SESSION['access_token'] = $this->api->getAccessToken();
    }

}
elseif(isset($_SESSION['access_token']) && ! isset($_REQUEST['signed_request'])) 
    $this->api->setAccessToken($_SESSION['access_token']);
elseif(isset($_REQUEST['signed_request'])) {
    Session::invalidate('fbuser');
    $_SESSION['access_token'] = '';
}

So gehe ich mit den Benutzerdaten um:

try {
    $this->user = Session::getVar('fbuser');
    if ($this->user === false || is_null($this->user)) {
        $facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');
        $this->user = new FBUserModel(array('fbId' => $facebookUser['fbId'], ...));
        Session::setVar('fbuser', $this->user);
    }
}


Das Problem

Beim Testen sieht alles gut aus. Nur wenn ein Fehler aufgetreten ist: das erste Mal nachdem die Erlaubnis gesetzt wurde. Nun, da die App online ist, scheint der Fehler durchschnittlich bei jedem zweiten Benutzer in zu sein

$facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');

mit dem Fehler:

An active access token must be used to query information about the current user.


Frage

Warum passiert das? Das Debuggen ist sehr schwierig, da der Fehler scheinbar nur dann auftritt, wenn ein Benutzer die App zum ersten Mal eingibt, nachdem die App-Authentifizierung und das Zugriffstoken geändert wurden. Und selbst das passiert nicht jedes Mal. Wie gehe ich mit dem neuen PHP SDK mit der Sitzung und dem Zugriffstoken um?

Jede Hilfe wird sehr geschätzt!


Bearbeiten

Ich habe herausgefunden, dass es einige IE Probleme mit Cookies/Sitzungen in einem iFrame gibt. Wie gesehen in diesem Blogbeitrag. Mit diesem Hinweis und einigen weiteren Nachforschungen fügte ich meinem Bootstrap folgende Zeilen hinzu:

ini_set('session.use_trans_sid', 1);
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

Jetzt ist es viel besser, aber die Informationen von ungefähr 2 von 50 Benutzern gehen zwischen den Schritten der Landing Page (Authentifizierung) -> Formular -> und der Registrierung verloren. Es gibt also noch etwas, was ich vermisst habe.


Bearbeiten 2

Ich habe meine Benutzerhandhabung von bearbeitet

if ($this->user === false || is_null($this->user)) {
    // get user data
}

zu

if ((is_object($this->user) && $this->user->fbId == '') || $this->user === false || is_null($this->user)) {
    // get user data
}

Das scheint ein bisschen zu helfen. Ich denke, das Hauptproblem liegt irgendwo in meiner Sitzung.

Außerdem fügte ich einen try/catch-Block hinzu, um zu sehen, ob irgendwo in meiner App eine OAuthException von Facebook geworfen wird. Wenn dies der Fall ist, leite ich die top-Position zur Facebook-Seite und zur Registerkarte weiter, um eine neue signierte Anfrage zu erhalten. Obwohl dies zur Lösung dieses Problems beitragen kann, möchte ich verhindern, dass meine App den Benutzer umleiten muss.


Bearbeiten 3

Nach einigen Tagen intensiven Fehlersuchens und Protokollierens fand ich heraus, dass der $_REQUEST['session'], der von der FB.ui-Methode permissions.request stammt, selten leer ist.

So gehe ich damit um:

Dies ist das Zeug, das ich immer dabei habe:

FB.provide("UIServer.Methods", {'permissions.request': {size : {width: 575, height: 300}, url: 'connect/uiserver.php', transform : FB.UIServer.genericTransform}});

Diese Funktion wird beim Senden des Formulars aufgerufen. Hat immer für mich gearbeitet, aber irgendwie sendet es trotzdem das Formular obwohl session == ''.

function getPermission(form) {

    session = $('#' + $(form).attr('id') + ' input[name="session"]');

    if($(session).val() != '') {
        form.submit();
        return;
    }

    FB.ui({method: "permissions.request", "perms": 'user_photos'}, function callback(info){
        if(info.status=='connected' && info.session !== null) {
            $(session).val(JSON.stringify(info.session));
            form.submit();
        }
    });
    return;
}
37
Sascha Galley

Meine Lösung

Nun, da alles, was ich tat, nur ein Workaround war, bis das neue JS SDK herauskam, scheint es keine Best Practice zu geben. Indem Sie session.use_trans_sid auf 1 setzen und den P3P-Header hinzufügen, konnten Sie die Probleme mit IE iFrame-Cookies beheben (siehe meine erste Bearbeitung). Nach ein paar Tagen des intensiven Debugging habe ich herausgefunden, dass der permission_request von FB.ui nicht jedes Mal ein neues Zugriffstoken sendet (<5%).

In diesem Fall ist etwas schief gelaufen. Aber dieses kleine Etwas macht mich verrückt. Da dies selten geschieht, kann ich die Benutzer zurück auf die Registerkarte "Facebook" umleiten, um eine neue signierte Anfrage zu erhalten. Mit dem neuen JS SDK wird dies hoffentlich nicht mehr passieren.

Update: Endlösung

Es gab eine Kleinigkeit, die ich übersehen habe und die Lösung kann hier gefunden werden: FB ist nicht definiert Problem
Ich habe das JS SDK nicht asynchron geladen []! Das erklärt alles. Manchmal wurde die Datei all.js nicht schnell genug geladen, sodass ein JS-Fehler aufgetreten ist. Daher funktionierte weder der Berechtigungsdialog noch die JS-Validierung und es wurde ein leerer #session-Eingabewert gesendet.

5
Sascha Galley

Ich benutze jetzt PHP SDK 3.x ohne Probleme.

Naitik, der Klassenautor hat die Funktion getSession () entfernt. Wenn Sie nun wissen möchten, ob der Benutzer authentifiziert ist oder nicht, verwenden Sie getUser () .

Für das Access-Token ist es sehr einfach, verwenden Sie diese Funktion getAccessToken () , und Sie erhalten das Zugriffstoken für Graph- oder Rest-APIAufrufe.

$user = $facebook->getUser();

if ($user) {
//USER Logged-In
}
else {
//USER not Logged-In
}

//TO GET ACCESS TOKEN
$access_token = $facebook->getAccessToken();


//MAKE AN API CALL WITH IT
$user_info = $facebook->api('me?fields=id,name,first_name,last_name&access_token='.$access_token);
10
Hamza

Für den Anfang würde ich ein wenig mehr debuggen. Protokollieren Sie den Inhalt der Anforderungen. Was wird in $ _SESSION gespeichert, was wird in $ _REQUEST übergeben? Überprüfen Sie auch, ob es sich um ein Browserproblem handelt (tritt es unabhängig vom Browser auf oder gibt es ein Muster?)

Da das Beheben des Cookie-Problems in IE (P3P-Header) jedoch hilfreich war, kann ich davon ausgehen, dass es einige Browser gibt, die Drittanbieter-Cookies ablehnen. Soweit ich weiß, machen einige Versionen von Safari und Opera dies standardmäßig. Außerdem gibt dieser Fehler an, dass kein access_token angegeben wurde, im Gegensatz zu ungültigem oder abgelaufenem.

Sie können dies testen, indem Sie Cookies von Drittanbietern deaktivieren ( beispielsweise mit about: config in firefox ) und die Deaktivierung Ihrer App (mit dem Abschnitt "Apps und Websites" am unteren Rand von Facebook-Datenschutz-Einstellungen ), Löschen von Cookies (bezogen auf Ihre Canvas-URL) und Starten der Anwendung.

BTW, es besteht immer die Möglichkeit, dass Facebook den Zugriffstoken nicht zurückgibt, selbst wenn dies der Fall ist, da beschrieben in Bug 17236

2

Hallo, ich bin in der gleichen Schwierigkeit gelaufen, ich habe es mit der Überwachung der JS-API gelöst und zur PHP-SDK-Anmeldeseite weitergeleitet, wenn Benutzerinformationen lesbar sind

beispiel: 

<script language="JavaScript">

function check_fb_status(){
    FB.api('/me', function(response){
     if(response.name) window.location='<?php echo $facebook->getLoginUrl(); ?>';
     else check_fb_status();
    });
}

check_fb_status();

</script>

wenn das Skript erfolgreich war, wird die Login-Seite geladen, und der Benutzer wurde sowohl von JS als auch von PHP SDK erkannt.

1
benny

Zu Ihrer Information hat Facebook vor etwa 2 Stunden ein Update für das PHP - SDK veröffentlicht, das Unterstützung für das neue Cookie-Format bietet, wenn Sie eine Sitzung auf dem Client mit dem JavaScript-SDK erstellen. Das Update ist im Facebook PHP-SDK GitHub Repo zu finden.

0
Rob DiMarco