iOS 6 Вход в Facebook не обновляет токен доступа

Ничто из того, что я читаю (много статей о разработчиках FB и SO-вопрос), не помогает, поэтому я решил опубликовать здесь. Я пытаюсь заставить все это работать с iOS 6 и Facebook SDK 3.1.1.

У меня довольно простая настройка: мое приложение для iOS аутентифицируется в Facebook, я передаю access_token на свой сервер, и теперь пользователь входит в мое приложение. Единственная другая вещь, которую они могут сделать, связанная с Facebook, — это опубликовать что-нибудь на своей стене. Я использую устаревшее диалоговое окно, чтобы пользователь мог добавлять свои собственные комментарии.

Все работает отлично на новой установке в течение первого часа или около того. Если пользователь вошел в систему через приложение «Настройки iOS», ему предоставляется окно быстрого подтверждения iOS, я получаю его токен, отправляю его на свой сервер, и все в порядке.

Если я вставлю полученный токен в отладчик токенов доступа Facebook, он покажет, что срок его действия истечет через час.

Если я подожду этот час и вернусь в приложение после этого, все, что я попытаюсь сделать, выдаст мне эту ошибку:

{"error_code":190,"
  error_msg":"Error validating access token: 
              Session has expired at unix time 1351497600. 
              The current unix time is 1351525180. }
  1. Что мне нужно сделать, чтобы все просто работало? я читал, что в SDK 3.1.1 FBSession просто позаботится об этом, но это не похоже на тот случай. Срок действия моего токена доступа истекает, и когда это произойдет, iOS/FB SDK не вернет мне обновленный.
  2. Даже выход из системы (который вызывает [FBSession.activeSession closeAndClearTokenInformation]) не решает этого. Единственное, что я смог сделать, это «Сбросить содержимое и настройки» в настройках симулятора iOS, повторно ввести свои учетные данные FB в Settings.app и перестроить мое приложение. Только тогда я смогу получить еще один токен, срок действия которого истекает через час.

Случайные заметки:

  1. Когда мое приложение возобновляет работу, я звоню [FBSession.activeSession handleDidBecomeActive] и [self.facebook extendAccessTokenIfNeeded].
  2. Согласно вопросу SO, указанному выше, SDK должен автоматически вызывать FBSession#renewSystemAuthorization. Я поместил туда NSLog и никогда не видел, чтобы этот метод вызывался.

ОБНОВЛЕНИЕ №1:

Я упомянул, что читал, что SDK будет обрабатывать недействительные токены или токены с истекшим сроком действия. Похоже, это должно произойти в FBRequestConnection#completeWithResults:orError:. См. встроенные комментарии для заметок о пути кода.

- (void)completeWithResults:(NSArray *)results
                orError:(NSError *)error
{
    int count = [self.requests count];
    for (int i = 0; i < count; i++) {
        FBRequestMetadata *metadata = [self.requests objectAtIndex:i];
        id result = error ? nil : [results objectAtIndex:i];
        NSError *itemError = error ? error : [self errorFromResult:result];

        id body = nil;
        if (!itemError && [result isKindOfClass:[NSDictionary class]]) {
            NSDictionary *resultDictionary = (NSDictionary *)result;
            body = [FBGraphObject graphObjectWrappingDictionary:[resultDictionary objectForKey:@"body"]];
        }

        ...

        // *******************************************
        // My code actually falls into this block, proving that I do in fact have an invalid session
        // *******************************************
        if ([self isInvalidSessionError:itemError
                        resultIndex:error == itemError ? i : 0]) {
            [metadata.request.session closeAndClearTokenInformation:itemError];

            // *******************************************
            // Unfortunately metadata.request.session is nil, so this condition is never
            // run, so renewySystemAuthorization is never called
            // *******************************************
            if (metadata.request.session.loginType == FBSessionLoginTypeSystemAccount){
                [FBSession renewSystemAuthorization];
        }
    }

    ...
}

person djibouti33    schedule 29.10.2012    source источник
comment
Вы уверены, что это долгоживущий токен доступа? О чем говорит дата истечения срока действия, когда вы вводите токен в отладчик. На моих токенах-долгожителях написано Expires: 1356716436 (примерно через 2 месяца)   -  person Donn Lee    schedule 29.10.2012
comment
Ха, это очень интересно. Хорошая идея. Подключаем его к отладчику (для тех, кто не знает: developers.facebook.com/tools/debug) говорит Срок действия: 1351540800 (примерно через час). Я чувствую, что очень внимательно следил за документацией и примерами SDK. Мое приложение отлично работает в течение первого часа, но после этого я просто не могу получить обновленный токен. Любые идеи?   -  person djibouti33    schedule 29.10.2012
comment
Не могли бы вы предоставить информацию о настройках панели приложений. Какова ваша настройка в разделе Advanced › Authentication в качестве примера. Что-нибудь еще, что отличается от документов, что вы можете придумать в своих настройках?   -  person C Abernathy    schedule 31.10.2012
comment
Хороший вопрос. Все они кажутся нормальными. Для Advanced › Auth у меня есть Web как тип и пусто для URL-адреса обратного вызова. Я думаю, что он должен оставаться веб-сайтом, а не нативным / настольным, потому что наш веб-сайт использует одно и то же приложение FB. Сегодня я попытался переключить его на Native/Desktop, и когда я подключил токен к отладчику, срок действия не истек. Мне это показалось странным, поэтому я поменял его обратно. Все остальное отключено или пусто, за исключением Social Discovery, Picture as Dict и URL-адреса сброса клиента установлено значение NO. В Основах у меня правильно настроено собственное приложение для iOS, включен вход через FB и отключено глубокое связывание.   -  person djibouti33    schedule 31.10.2012
comment
@ djibouti33 - у меня та же проблема, которую я описываю здесь: заголовок stackoverflow.com/questions/13242787/. Вы пришли к решению? Я рассматриваю несколько, но еще не уверен в лучшем подходе.   -  person TomSwift    schedule 06.11.2012


Ответы (1)


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

Во-первых, оказывается, что старые версии нашего приложения запрашивали offline_access. Я не знал этого. Я зашел в «Настройки» моего приложения FB> «Дополнительно» и включил «Удалить разрешение offline_access». Теперь я получаю токен, который действует два месяца (проверьте отладчик токенов facbeook).

Теперь, когда я возвращаю токен правильного типа, у меня все еще есть проблема с возвратом действительного токена, когда он был деактивирован/истек. Поскольку теперь я получаю токен на 2 месяца, я не могу дождаться истечения срока его действия, поэтому мой план состоял в том, чтобы вызвать исключение OAuthException, зайдя в настройки моей учетной записи и деавторизовав его.

В моем appDidBecomeActive я установил [FBRequestConnection startForMeWithCompletionHandler:nil], чтобы просто инициировать тихий запрос к FB, и когда это не удается из-за недопустимого сеанса/токена, поток кода проходит по правильному пути, и [FBSession renewSystemAuthorization] в конечном итоге вызывается , что в конечном итоге мне и было нужно. Это позволяет iOS сделать следующее: когда я в следующий раз войду в свое приложение через FB, iOS снова предложит мне, понимая, что у меня больше нет действительного токена. Вызов [FBSession renewSystemAuthorization] эффективно сообщает iOS, что в следующий раз, когда мое приложение запросит доступ, нажмите facebook и верните мне новый/обновленный токен.

По большей части сейчас все работает так, как ожидалось.

person djibouti33    schedule 08.11.2012
comment
Где найти «Настройки приложения FB» > «Дополнительно» и включить разрешение «Удалить offline_access». я не могу найти - person Erik; 30.04.2013
comment
хм, похоже, это было удалено. некоторые поиски показывают, что он устарел/удален в следующем месяце или около того, но, возможно, если бы он не был включен, они просто полностью скрыли бы его. попробуйте пропустить этот шаг и выполнить остальные и посмотреть, к чему это приведет. - person djibouti33; 30.04.2013