iOS 6 Facebook登录不刷新访问令牌

dji*_*i33 3 iphone facebook objective-c facebook-access-token ios6

我正在阅读的内容(许多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. }
Run Code Online (Sandbox Code Playgroud)
  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#completionWithResults: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];
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

dji*_*i33 7

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

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

既然我正在找回正确类型的令牌,那么当它已被停用/过期时,我仍然有一个问题.由于我现在回来了两个月的令牌,我不能等到它过期,所以我的计划是通过进入我的帐户设置并取消授权来触发OAuthException.

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

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