как обновить токен oauth при использовании Facebook iPhone SDK - PullRequest
13 голосов
/ 31 августа 2010

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

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

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

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

Помощь!

Ответы [ 6 ]

3 голосов
/ 19 ноября 2014

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

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 голосов
/ 02 февраля 2011

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

У вас есть 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, которая делает то же самое (никогда с ней не работал, поэтому я не могу сказать). Этот тип запроса не будет запрашивать у пользователя повторный вход, но будет использовать предыдущий сеанс, который был создан во время первого входа.

0 голосов
/ 27 июля 2018

На сегодняшний день Facebook должен обновлять токены автоматически, запросы к GraphAPI могут выполняться без указания строки токена (Facebook обрабатывает ее под капотом).

Более того, если случится так, что пользователь долгое время не использовал приложение и срок действия его токена истек, при следующем запросе к Graph API SDK Facebook будет показывать предупреждение с просьбой о повторной регистрации (все, что обрабатывается). через Facebook, и когда все будет готово - вернется в закрытие FBSDKGraphRequest.

enter image description here

Однако, если у кого-то действительно есть причина обновить токен доступа вручную, вот пример (Swift 4):

private var selfDestructableNotificationToken: NotificationTokenThatAutomaticallyRemovesObserver?
final class NotificationTokenThatAutomaticallyRemovesObserver: NSObject { // more info here: https://oleb.net/blog/2018/01/notificationcenter-removeobserver/
    let token: Any
    init(_ token: Any) { self.token = token }
    deinit { NotificationCenter.default.removeObserver(token) }
}

...

if let currentFBToken = FBSDKAccessToken.current() { // if this is a Facebook user, not an email-based user
    if FBSDKAccessToken.currentAccessTokenIsActive() { // and his token has not expired yet
        let token = NotificationCenter.default.addObserver(forName: NSNotification.Name.FBSDKAccessTokenDidChange, object: nil, queue: OperationQueue.main) { notification in
            if let userInfo = notification.userInfo, let refreshedToken = userInfo["FBSDKAccessToken"] as? FBSDKAccessToken {
                self.fbAccessToken = refreshedToken.tokenString
            } else {
                self.fbAccessToken = currentFBToken.tokenString // falling back to using an old token (better than none)
            }
        }
        self.selfDestructableNotificationToken = NotificationTokenThatAutomaticallyRemovesObserver(token)
        FBSDKAccessToken.refreshCurrentAccessToken { _, _, error in
            if let error = error {
                print("failed to refresh Facebook token with error \(error.localizedDescription)")
                self.fbAccessToken = currentFBToken.tokenString // falling back to an old token (better than none)
            }
        }
    } else if FBSDKAccessToken.current().isExpired { // unlucky user. Probably returned to the app after > 2 months break
        self.fbAccessToken = currentFBToken.tokenString // assigning expired token. Facebook will ask user to relogin as soon as we call Graph API with that expired token
    }
}
0 голосов
/ 06 мая 2014

Согласно документации SDK Facebook:

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

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

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

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

0 голосов
/ 05 октября 2010

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

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

0 голосов
/ 31 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...