it-swarm.com.ru

Facebook SDK 3.1 - Ошибка при проверке токена доступа

Я пытаюсь перевести мое приложение на новый Facebook SDK 3.1 (с поддержкой аутентификации iOS6).

У меня все работало нормально, поэтому я решил удалить приложение из своего списка авторизованных приложений на веб-сайте FB, чтобы проверить, что iOS снова запросит разрешение.

Теперь мой первый вызов [FBRequest requestForMe] вызывает эту ошибку:

Отклик:

{
  "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
  }
}

Некоторые детали:

Я пытаюсь открыть сессию следующим образом:

   [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;
                                           }

Затем мне перезванивают в состоянии FBSessionStateOpen (на данный момент iOS не представила диалоговое окно запроса, это ожидалось)? Facebook регистрирует это:

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 

Как только сессия открыта, в presentPostOptions я делаю это:

- (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];
        }
    }];
}

До того как вышеуказанный блок завершения вызывается обратно, мой блок основного состояния вызывается с состоянием FBSessionStateClosed. Тем временем SDK Facebook зарегистрировал вышеупомянутую ошибку.

Я не могу найти способ перезагрузить систему; и я действительно не понимаю причину.

Кто-нибудь может пролить немного света?

36
tarmes

Учетная запись Facebook на устройстве вышла из синхронизации с сервером, а также с кэшем приложения/SDK. Это можно решить, вызвав метод ACAccountStore renewCredentialsForAccount, который обновит понимание ОС состояния токена.

В следующем обновлении SDK SDK автоматически вызовет этот API, когда получит ответ от сервера, указывающий, что токен стал недействительным. Для версии SDK 3.1.0 приложения должны будут явно вызывать этот API. Вот пример кода:

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){

            }
        }];
    }
}

Есть несколько вариантов, где/когда вызывать API. Самое простое место - сделать вызов при запуске приложения или при загрузке просмотра. Одна проблема с этим подходом состоит в том, что он вызовет двустороннюю передачу по сети, которая часто не нужна. Другой вариант - вызывать его, когда происходит уведомление об изменении сеанса, указывающее, что сеанс закрыт. Также многие приложения извлекают некоторую основную информацию, такую ​​как graph.facebook.com/me, во время запуска приложения и, если так, - вызов этого метода в случае ответа об ошибке может быть разумным местом, чтобы попросить iOS обновить свой токен. статус. 

Надеюсь, это поможет!

76
Jason Clark

Я просто хочу добавить еще одну вещь, чтобы проверить, что я потратил впустую 3 часа: Убедитесь, что в настройках вашего приложения FB не включена опция «Песочница», если вы пытаетесь войти в систему, не используя приложение. разработчик FB user ... Может быть, очевидно, но, надеюсь, может сэкономить другим несколько часов.

7
snowdragon

Попробуйте добавить, если вы еще этого не сделали, свой идентификатор пакета приложения iOS на панели настроек вашего приложения Facebook, как предложено здесь .

Надеюсь это поможет.

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

Я вполне уверен, что это ошибка SDK Facebook iOS (даже на 3.1.1), и я подал этот отчет об ошибках .

Пытаясь воспроизвести эту ошибку с помощью примера приложения Scrumpious, я обнаружил, что он позволяет успешно выполнить повторную авторизацию, если вы используете openActiveSessionWithReadPermissions. Однако, если вы запрашиваете разрешения на публикацию через openActiveSessionWithPublishPermissions, он застрянет в com.facebook.sdk.error 5.

1
Min Kim

В фейсбуке SDK 3.7.1 у меня осталась эта проблема. По сути, я решил очистить токен из кэша Facebook, когда это произойдет. Как это:

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

Простое решение Swift 2+ для Facebook Ошибка проверки токена доступа

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

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

// ...

}

Если эта ошибка возникает, вы должны создать новую сессию Facebook , поэтому вам придется снова войти в систему.

0
fatihyildizhan