web-dev-qa-db-fra.com

Facebook SDK 3.1 - Erreur de validation du jeton d'accès

J'essaie de migrer mon application vers le nouveau SDK Facebook 3.1 (avec prise en charge de l'authentification iOS6).

Cela fonctionnait très bien. J'ai donc décidé de supprimer l'application de ma liste d'applications autorisées sur le site Web de FB afin de vérifier qu'iOS demanderait de nouveau l'autorisation.

Maintenant, mon premier appel à [FBRequest requestForMe] provoque cette erreur:

Réponse:

{
  "error": {
    "message": "Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.",
    "type":"OAuthException",
    "code":190,
    "error_subcode":460
  }
}

Quelques détails:

J'essaie d'ouvrir la session comme suit:

   [FBSession openActiveSessionWithReadPermissions:nil
                                       allowLoginUI:YES
                                  completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {

                                           switch (state) {
                                               case FBSessionStateOpen:
                                                   [self presentPostOptions];
                                                   break;

                                               case FBSessionStateClosed:
                                               case FBSessionStateClosedLoginFailed:
                                                   [FBSession.activeSession closeAndClearTokenInformation];
                                                   break;

                                               default:
                                                   break;
                                           }

Je suis ensuite rappelé dans l'état FBSessionStateOpen (à ce stade, iOS n'a pas présenté de boîte de dialogue de requête, est-ce à prévoir)? Facebook enregistre ceci:

2012-09-26 13:43:43.768 MyApp[2177:907] FBSDKLog: FBSession INVALID transition from FBSessionStateCreated to FBSessionStateClosed
2012-09-26 13:43:43.769 MyApp[2177:907] FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening 
2012-09-26 13:43:43.837 MyApp[2177:907] FBSDKLog: FBSession transition from FBSessionStateCreatedOpening to FBSessionStateOpen 

Une fois la session ouverte, dans presentPostOptions je fais ceci:

- (void)presentPostOptions
{    
    [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
        if (!error) {
            self.usersName = user.name;
            self.usersID = user.id;

            [self getPages];
        }
        else
        {
            [self didFailWithError:error];
        }
    }];
}

Avant que le bloc d'achèvement ci-dessus ne soit rappelé, mon bloc de gestionnaire d'état principal est appelé avec un état FBSessionStateClosed. Dans l'intervalle, le SDK de Facebook a consigné l'erreur ci-dessus.

Je ne trouve aucun moyen de réinitialiser le système. Je ne comprends pas vraiment la cause.

Quelqu'un peut-il s'il vous plaît faire la lumière?

36
tarmes

Le compte Facebook de l'appareil est désynchronisé avec le serveur et avec le cache de l'application/SDK. Pour résoudre ce problème, appelez la méthode ACAccountStore renewCredentialsForAccount, qui mettra à jour la compréhension de l'état du jeton par le système d'exploitation.

Lors de la prochaine mise à jour du SDK, le SDK appellera automatiquement cette API lorsqu'il recevra une réponse du serveur indiquant qu'un jeton est devenu invalide. Pour la révision 3.1.0 du SDK, les applications devront appeler explicitement cette API. Voici un exemple de code:

ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) &&
    (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){

    NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
    id account;
    if (fbAccounts && [fbAccounts count] > 0 &&
        (account = [fbAccounts objectAtIndex:0])){

        [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
            //we don't actually need to inspect renewResult or error.
            if (error){

            }
        }];
    }
}

Il y a plusieurs options pour où/quand appeler l'API. Le plus simple serait d’appeler de manière opportuniste lors du lancement de l’application ou lors du chargement de la vue. Un problème avec cette approche est qu’elle entraînera un aller-retour du réseau qui est souvent inutile. Une autre option consiste à l'appeler lorsqu'une notification de changement de session se produit, indiquant qu'une session est fermée. En outre, de nombreuses applications récupèrent des informations de base telles que graph.facebook.com/me, au moment du lancement de l'application et, le cas échéant, un appel à cette méthode en cas de réponse d'erreur peut être un endroit raisonnable pour demander à iOS de mettre à jour son jeton. statut. 

Espérons que cela aide!

76
Jason Clark

Je vais simplement contribuer à un autre point à vérifier qui m'a fait perdre 3 heures: Assurez-vous que les paramètres de votre application FB ne disposent pas de l'option "Sandbox" si vous essayez de vous connecter avec une application non-app- développeur FB utilisateur ........ Peut-être évident, mais pourrait permettre aux autres de gagner quelques heures, espérons-le.

7
snowdragon

Essayez d'ajouter, si vous ne l'avez pas déjà fait, votre identifiant de paquet d'applications iOS dans le panneau paramètres de votre application Facebook, comme suggéré ici .

J'espère que cela t'aides.

4
Cyupa
[FBSession openActiveSessionWithReadPermissions:nil
 allowLoginUI:YES
 completionHandler:^(FBSession *session, FBSessionState  state, NSError *error) 
    {

       switch (state) {
           case FBSessionStateOpen:
               [self presentPostOptions];
               break;

           case FBSessionStateClosed:
           case FBSessionStateClosedLoginFailed:
               [FBSession.activeSession closeAndClearTokenInformation];
               break;

           default:
               break;
       }

      }];   
1
user4431517

Je suis à peu près sûr qu'il s'agit d'un bogue du SDK Facebook iOS (même sur la version 3.1.1) et j'ai classé ce rapport de bogue .

En essayant de reproduire ce bogue en utilisant leur exemple d’application Scrumptious, j’ai constaté qu’il vous permettait de ré-autoriser avec succès si vous utilisiez openActiveSessionWithReadPermissions. Toutefois, si vous demandez des autorisations de publication via openActiveSessionWithPublishPermissions, il serait bloqué dans com.facebook.sdk.error 5.

1
Min Kim

Dans facebook SDK 3.7.1, j'avais toujours ce problème. Fondamentalement, j'ai décidé d'effacer le jeton du cache facebook lorsque cela se produit. Comme ça:

if(state == FBSessionStateClosed ) {
     [FBSession.activeSession closeAndClearTokenInformation];
}
0
Tiago Almeida

Simple Swift 2+ Solution pour Facebook Erreur de validation du jeton d'accès

// Step 1: Logout 
FBSDKLoginManager().logOut()

// Step 2: Login
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"], fromViewController: self, handler: { result, error -> Void in 

// ...

}

Si cette erreur se produit, vous devez créer un nouveau Facebook Session , vous devez donc vous reconnecter.

0
fatihyildizhan