Dans le SDK PHP 3.0, il n'y a pas de getSession()
ou de gestion de session disponible en dehors de l'api Facebook. Il y a quelques jours, les développeurs de Facebook ont également mis à jour le sdk JavaScript, selon ce billet de blog et ce rapport de bug.
Au cours des derniers jours, un changement a été introduit dans le SDK JS hébergé qui a cassé toute compatibilité entre lui et le SDK PHP actuel (2.x and 3.x). Les développeurs qui utilisent à la fois le SDK JS et PHP sur leurs sites web risquent de rencontrer des échecs de l'API côté serveur.
Cependant, je ne sais pas si cela affecte vraiment mon problème. Comme dans la réponse à cette question, j'obtiens le jeton d'accès du dialogue OAuth avec PHP et enregistre le nouveau jeton d'accès en session.
Solution de contournement actuelle
Le code suivant montre comment je gère ces sessions. $_REQUEST['session']
est le contenu de la réponse du dialogue OAuth.
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'] = '';
}
Voici comment je gère les données utilisateur :
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);
}
}
Le Problème
Tout semble correct lors des tests. Seule une fois une erreur s'est produite : la première fois après que l'autorisation ait été définie. Maintenant, depuis que l'application est en ligne, il semble que l'erreur se produise en moyenne avec chaque deuxième utilisateur dans
$facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');
avec l'erreur :
Un jeton d'accès actif doit être utilisé pour interroger les informations sur l'utilisateur actuel.
Question
Pourquoi cela se produit-il ? C'est très difficile à déboguer car l'erreur semble se produire uniquement lorsque qu'un utilisateur entre dans l'application pour la première fois, après l'authentification de l'application et que le jeton d'accès a changé. Et même cela ne se produit pas à chaque fois. Comment devrais-je gérer la session et le jeton d'accès correctement avec le nouveau SDK PHP ?
Toute aide serait grandement appréciée !
Édition
J'ai découvert qu'il y a des problèmes IE avec les cookies/sessions à l'intérieur d'un iFrame. Comme vu dans ce billet de blog. Avec ce conseil et quelques recherches supplémentaires, j'ai ajouté les lignes suivantes dans mon bootstrap :
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"');
Maintenant c'est bien mieux, mais les informations de près de 2 utilisateurs sur 50 se perdent entre les étapes de la page de destination (authentification) -> formulaire -> et enregistrement. Il y a donc encore quelque chose que j'ai raté.
Édition 2
J'ai modifié ma gestion des utilisateurs de
if ($this->user === false || is_null($this->user)) {
// obtenir les données de l'utilisateur
}
à
if ((is_object($this->user) && $this->user->fbId == '') || $this->user === false || is_null($this->user)) {
// obtenir les données de l'utilisateur
}
Cela semble aider un peu. Je pense que le problème principal se situe quelque part dans ma session.
De plus, j'ai ajouté un bloc try/catch pour voir si une exception Facebook OAuthException
est lancée quelque part dans mon application. Si tel est le cas, je redirige vers la top location de la Page et du Tab de Facebook pour obtenir un nouveau signed request. Bien que cela puisse aider à résoudre ce problème, je veux éviter que mon application ne doive rediriger l'utilisateur.
Édition 3
Après quelques jours d'intense débogage et de journalisation, j'ai découvert que le $_REQUEST['session']
provenant de la méthode FB.ui permissions.request est parfois vide.
Voici comment je le gère :
Voici les choses que j'inclus toujours :
FB.provide("UIServer.Methods", {'permissions.request': {size : {width: 575, height: 300}, url: 'connect/uiserver.php', transform : FB.UIServer.genericTransform}});
Et cette fonction est appelée lors de la soumission du formulaire. Cela a toujours fonctionné pour moi, mais pour une raison quelconque, il envoie toujours le formulaire même si 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;
}