Как обновить токен oauth при использовании iPhone iPhone SDK

Я использую Facebook SDK для iOS в своем приложении: http://github.com/facebook/facebook-ios-sdk

токен oAuth истекает через 2 часа. Как я могу "обновить" токен oAuth без повторного вызова метода [Facebook authorize...] - который показывает пустой диалог Facebook, если пользователь ранее вошел в систему? То, что я хочу избежать, требует от пользователя повторного входа в FB каждый раз, когда они используют приложение, например, каждый день.

Я уже сохраняю/восстанавливаю токены oAuth, когда приложение выходит/запускается. И я могу проверить, действителен ли токен, используя [Facebook isSessionValid], или проверять время истечения срока действия на токене. Но что делать, если токен истек? Я прочитал, что можно "обновить" токен, но я не понимаю, как это делается.

Я не хочу запрашивать разрешение "offline_access", которое даст мне токен "навсегда".

Help!

Ответы

Ответ 1

Реализация Facebook OAuth не поддерживает обновление токена.

У вас есть 2 типа access_tokens в Facebook. Краткосрочный токен, который задается по умолчанию и долгосрочный токен, который предоставляется, если вы запрашиваете offline_access. Если обновлен токен обновления, он был таким же, как предоставление токена offline_access для всех приложений.

Пока пользователь имеет активный сеанс facebook в вашем веб-элементе управления, вы можете запросить новый access_token, просто обратившись к https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=http://www.facebook.com/connect/login_success.html&response_type=token или вероятно, какая-то команда IOS SDK, которая делает то же самое (никогда не работала с ней, поэтому я не могу сказать). Такой запрос не будет запрашивать у пользователя логин снова, но будет использовать предыдущий сеанс, который был создан во время первого входа.

Ответ 2

Поскольку ни один из этих ответов на самом деле не затронул вопрос, я подробно расскажу о том, как я обновил токен OAuth, используя The Facebook SDK.

SDK автоматически обновит ваши жетоны, когда вы делаете запросы, однако в моем сценарии мы отправляем токены на наши серверы, и нам нужно использовать последний токен. Поэтому, когда наш сервер указывает, что нам нужны новые токены, это то, что мы делаем:

Примечание. Вы можете либо передать AppID в FBSession, либо добавить свой FacebookAppID в свой аппликатор (это то, что мы делаем).

- (void)renewFacebookCredentials {
    if (FBSession.activeSession.state == FBSessionStateOpen ||
        FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
        [self sessionStateChanged:[FBSession activeSession] state:[FBSession activeSession].state error:nil];
    } else {
        // Open a session showing the user the login UI
        // You must ALWAYS ask for public_profile permissions when opening a session
        [FBSession openActiveSessionWithReadPermissions:@[@"public_profile",@"email"]
                                           allowLoginUI:NO
                                      completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
                                          //this block will run throughout the lifetime of the app.
                                          [self sessionStateChanged:session state:state error:error];
                                      }];
    }
}

Вы можете использовать метод sessionStateChanged:, который Facebook включает в свою документацию, но упрощенный обработчик выглядит следующим образом:

- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error {
    // If the session was opened successfully
    NSString *accessToken;
    if (!error && state == FBSessionStateOpen && [[session accessTokenData] accessToken]){
        // Show the user the logged-in UI

        //@see http://stackoverflow.com/questions/20623728/getting-username-and-profile-picture-from-facebook-ios-7
        accessToken = [[session accessTokenData] accessToken];
       //Now we have an access token, can send this to the server...
    } else {
       //No access token, show a dialog or something
    }

   //either call a delegate or a completion handler here with the accessToken
}

Имейте в виду, что некоторые API-интерфейсы FBSession проверяют привязку потоков, поэтому я обнаружил, что мне пришлось обернуть все мои вызовы FBSession внутри dispatch_async(dispatch_get_main_queue(), ^{...

Ответ 3

Просто выполните [[FBSession session] resume], если он вернет false, снова войдите в систему

Ответ 4

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

См. пример приложения facebook-ios-sdk/sample/DemoApp/Classes/DemoAppViewController.m для fbDidLogin, fbDidNotLogin и fbDidLogout методов

Ответ 5

В соответствии с документацией к SDK для Facebook:

SDK Facebook автоматически обновляет сеанс пользователя, если необходимо. Когда он это делает, состояние также переходит к FBSessionStateOpenTokenExtended.

Также для дальнейшего уточнения (начиная с SDK версии 3.1):

SDK обновляет сеанс автоматически при вызовах API.

Он также обновляет данные маркера по мере необходимости при последующих проверках подлинности или вызовах API Facebook, выполненных с использованием SDK.