【问题标题】:Expired access token after openActiveSession for Facebook iOS SDKFacebook iOS SDK 的 openActiveSession 后访问令牌过期
【发布时间】:2012-09-18 17:20:16
【问题描述】:

我正在使用 3.1 Facebook SDK,在“设置”中设置了 iOS 6 Facebook,并且我的应用已获得授权。

完美执行:

[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *fbSession, FBSessionState fbState, NSError *error) { ... }

但是现在当我尝试获取“我”信息时,我遇到了一个错误:

com.facebook.sdk:ParsedJSONResponseKey = {
    body =     {
        error =         {
            code = 190;
            "error_subcode" = 463;
            message = "Error validating access token: Session has expired at unix time 1348704000. The current unix time is 1348706984.";
            type = OAuthException;
        };
    };
    code = 400;
}

如果我查看[error code],它等于5。我不应该在刚登录后获得有效的访问令牌吗?我需要调用 reauthorize 吗?

更新:重新授权没有帮助。奇怪的是,我的 activeSession 的 accessToken 总是一样的。尽管调用了 closeAndClearToken。

【问题讨论】:

  • 要开始诊断,您能否记录您获得的 access_token 并将其粘贴到 developers.facebook.com/tools/debug - 时间戳就在那里?
  • 好提示。现在问题已经消失了,我需要重新创建它。下次看到你的建议我会试试的。
  • 我在使用 iPhone5/iOS6 时遇到了同样的问题。不过,这似乎很零星。如果您发现有关此问题的更多信息,请告诉我,我也会这样做。
  • 我遇到了完全相同的问题。看起来 accessToken 缓存在 NSUserDefaults 中并由 FBSession 检索,即使 closeAndClearToken 应该核对它。
  • 这里是直接在 SDK 中修复此问题的更新 (3.1.1):github.com/downloads/facebook/facebook-ios-sdk/… 谢谢!!

标签: ios facebook login


【解决方案1】:

所以它已经解决了,但是我一直从我们的后端调用 /me 来验证,因为你不能信任这个设备。

所以当后端返回授权错误时,我会调用FBSession+ (void)renewSystemAuthorization

【讨论】:

【解决方案2】:

更新: 此问题已在 Facebook iOS SDK 3.1.1 中得到解决。


我从 github 同步了代码,发现他们没有在任何地方调用 accountStore renewCredentialsForAccount:completion:。我在authorizeUsingSystemAccountStore中更改了以下代码,似乎已经解决了问题。

// we will attempt an iOS integrated facebook login
[accountStore requestAccessToAccountsWithType:accountType
                                      options:options
                                   completion:^(BOOL granted, NSError *error) {

                                       // this means the user has not signed-on to Facebook via the OS
                                       BOOL isUntosedDevice = (!granted && error.code == ACErrorAccountNotFound);

                                       dispatch_block_t postReauthorizeBlock = ^{
                                           NSString *oauthToken = nil;
                                           if (granted) {                                                                                                      
                                               NSArray *fbAccounts = [accountStore accountsWithAccountType:accountType];
                                               id account = [fbAccounts objectAtIndex:0];
                                               id credential = [account credential];                                                   
                                               oauthToken = [credential oauthToken];
                                           }

                                           // initial auth case
                                           if (!isReauthorize) {
                                               if (oauthToken) {
                                                   _isFacebookLoginToken = YES;
                                                   _isOSIntegratedFacebookLoginToken = YES;

                                                   // we received a token just now
                                                   self.refreshDate = [NSDate date];

                                                   // set token and date, state transition, and call the handler if there is one
                                                   [self transitionAndCallHandlerWithState:FBSessionStateOpen
                                                                                     error:nil
                                                                                     token:oauthToken
                                                    // BUG: we need a means for fetching the expiration date of the token
                                                                            expirationDate:[NSDate distantFuture]
                                                                               shouldCache:YES
                                                                                 loginType:FBSessionLoginTypeSystemAccount];
                                               } else if (isUntosedDevice) {
                                                   // even when OS integrated auth is possible we use native-app/safari
                                                   // login if the user has not signed on to Facebook via the OS
                                                   [self authorizeWithPermissions:permissions
                                                                  defaultAudience:defaultAudience
                                                                   integratedAuth:NO
                                                                        FBAppAuth:YES
                                                                       safariAuth:YES
                                                                         fallback:YES
                                                                    isReauthorize:NO];
                                               } else {
                                                   // create an error object with additional info regarding failed login
                                                   NSError *err = [FBSession errorLoginFailedWithReason:nil
                                                                                              errorCode:nil
                                                                                             innerError:error];

                                                   // state transition, and call the handler if there is one
                                                   [self transitionAndCallHandlerWithState:FBSessionStateClosedLoginFailed
                                                                                     error:err
                                                                                     token:nil
                                                                            expirationDate:nil
                                                                               shouldCache:NO
                                                                                 loginType:FBSessionLoginTypeNone];
                                               }
                                           } else { // reauth case
                                               if (oauthToken) {
                                                   // union the requested permissions with the already granted permissions
                                                   NSMutableSet *set = [NSMutableSet setWithArray:self.permissions];
                                                   [set addObjectsFromArray:permissions];

                                                   // complete the operation: success
                                                   [self completeReauthorizeWithAccessToken:oauthToken
                                                                             expirationDate:[NSDate distantFuture]
                                                                                permissions:[set allObjects]];
                                               } else {
                                                   // no token in this case implies that the user cancelled the permissions upgrade
                                                   NSError *error = [FBSession errorLoginFailedWithReason:FBErrorReauthorizeFailedReasonUserCancelled
                                                                                                errorCode:nil
                                                                                               innerError:nil];
                                                   // complete the operation: failed
                                                   [self callReauthorizeHandlerAndClearState:error];

                                                   // if we made it this far into the reauth case with an untosed device, then
                                                   // it is time to invalidate the session
                                                   if (isUntosedDevice) {
                                                       [self closeAndClearTokenInformation];
                                                   }
                                               }
                                           }
                                       };



                                       if (granted) {
                                           [accountStore renewCredentialsForAccount:[[accountStore accountsWithAccountType:accountType] lastObject] completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
                                               dispatch_async(dispatch_get_main_queue(), postReauthorizeBlock);
                                           }];
                                       } else {
                                           // requestAccessToAccountsWithType:options:completion: completes on an
                                           // arbitrary thread; let's process this back on our main thread
                                           dispatch_async(dispatch_get_main_queue(), postReauthorizeBlock);
                                       }

                                   }];

}

【讨论】:

  • 我们可能应该在续订之前检查 expiryDate(因为续订需要时间),但是尽管 Apple 的文档 (developer.apple.com/library/ios/#documentation/Accounts/…) 中说了什么,但 expiryDate 参数似乎并不存在。
  • 嗨,Ben,您说得对,需要致电 renew*。从这里调用效果很好。在哪里进行调用的选择通常取决于行为一致性和额外的网络往返之间的权衡。在下一次 SDK 更新中,我们正在考虑在处理无效令牌的 FBRequestConnection 逻辑中进行调用。
  • @JasonClark 这似乎是一个合理的选择。我建议在 FB SDK 中也有一个普通的旧更新调用。如果您只是将 SDK 用于令牌管理而不是用于进行图形调用的管道,那将很有用。感谢您的回复!
  • 嗨,Ben,您添加辅助方法的建议很好,我们将在下一次更新中这样做。目前我们已经完成了一个较小的 dot-release,它隐式地修复了同步问题,但不对公共 API 表面进行任何更改。这是 SDK 更新 (3.1.1) 的链接:github.com/downloads/facebook/facebook-ios-sdk/… 谢谢!!
猜你喜欢
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
  • 2016-01-14
  • 1970-01-01
相关资源
最近更新 更多