3

我正在阅读的任何内容(许多 FB 开发文章和 SO 问题)都没有帮助,所以我想我会在这里发帖。我试图让这一切都与 iOS 6 和 Facebook SDK 3.1.1 一起工作。

我有一个非常基本的设置:我的 iOS 应用程序通过 Facebook 进行身份验证,我将 access_token 传递给我的服务器,用户现在已登录到我的应用程序。他们唯一能做的与 facebook 相关的事情就是在他们的墙上贴一些东西。我正在使用旧版 Dialog 窗口,因此用户可以添加自己的评论。

在第一个小时左右的新安装中,一切都可以完美运行。如果用户通过 iOS 设置应用程序登录,他们会看到一个快速的 iOS 确认框,我得到他们的令牌,将其发送到我的服务器,我们都很好。

如果我将收到的令牌粘贴到 Facebook 的 Access Token 调试器中,它会显示它将在一小时后过期。

如果我等了那个小时然后回到应用程序,我尝试做的任何事情都会给我这个错误:

{"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 模拟器首选项中“重置内容和设置”,在 Settings.app 中重新输入我的 FB 凭据,然后重建我的应用程序。只有这样我才能获得另一个将在一小时内到期的令牌。

散记:

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

    ...
}
4

1 回答 1

7

这不是我所追求的修复类型,但事情看起来按预期工作,所以此时我只需要发货。

首先,事实证明我们的应用程序的旧版本正在请求offline_access。我不知道。我进入了我的 FB 应用程序的设置 > 高级,并启用了“删除离线访问权限”。我现在要取回一个持续两个月的令牌(查看 facbeook 令牌调试器)。

现在我取回了正确类型的令牌,但当它被停用/过期时,我仍然无法取回有效令牌。因为我现在要取回一个 2 个月的令牌,所以我等不及它过期了,所以我的计划是通过进入我的帐户设置并取消授权来触发 OAuthException。

在我的 appDidBecomeActive 中,我将 [FBRequestConnection startForMeWithCompletionHandler:nil] 用于简单地触发对 FB 的静默请求,当由于无效会话/令牌而失败时,代码流将通过正确的路径运行,并且 [FBSession renewSystemAuthorization] 最终被调用,这最终是我所需要的。这允许 iOS 做的是下次我通过 FB 登录到我的应用程序时,iOS 再次提示我,了解我不再拥有有效的令牌。调用 [FBSession renewSystemAuthorization] 有效地告诉 iOS,下次我的应用程序请求访问时,点击 facebook 并给我一个新的/刷新的令牌。

在大多数情况下,现在一切都按预期工作。

于 2012-11-08T22:14:48.827 回答