37

我正在尝试将我的应用程序转换到新的 Facebook SDK 3.1(支持 iOS6 身份验证)。

我让它工作得很好,所以我决定从我在 FB 网站上的授权应用程序列表中删除该应用程序,以测试 iOS 是否会再次请求许可。

现在我第一次调用[FBRequest requestForMe]导致此错误:

回复:

{
  "error": {
    "message": "Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.",
    "type":"OAuthException",
    "code":190,
    "error_subcode":460
  }
}

一些细节:

我正在尝试按如下方式打开会话:

   [FBSession openActiveSessionWithReadPermissions:nil
                                       allowLoginUI:YES
                                  completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {

                                           switch (state) {
                                               case FBSessionStateOpen:
                                                   [self presentPostOptions];
                                                   break;

                                               case FBSessionStateClosed:
                                               case FBSessionStateClosedLoginFailed:
                                                   [FBSession.activeSession closeAndClearTokenInformation];
                                                   break;

                                               default:
                                                   break;
                                           }

然后我在状态下被回调FBSessionStateOpen(此时 iOS 还没有显示请求对话框,这是意料之中的吗)?Facebook 记录了这一点:

2012-09-26 13:43:43.768 MyApp[2177:907] FBSDKLog: FBSession INVALID transition from FBSessionStateCreated to FBSessionStateClosed
2012-09-26 13:43:43.769 MyApp[2177:907] FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening 
2012-09-26 13:43:43.837 MyApp[2177:907] FBSDKLog: FBSession transition from FBSessionStateCreatedOpening to FBSessionStateOpen 

会话打开后,在 presentPostOptions 中我会这样做:

- (void)presentPostOptions
{    
    [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
        if (!error) {
            self.usersName = user.name;
            self.usersID = user.id;

            [self getPages];
        }
        else
        {
            [self didFailWithError:error];
        }
    }];
}

在回调上述完成块之前,我的主状态处理程序块被调用一个FBSessionStateClosed状态。与此同时,Facebook SDK 记录了上述错误。

我找不到任何方法来重置系统;我也不是很了解原因。

任何人都可以阐明一下吗?

4

7 回答 7

76

设备上的 Facebook 帐户与服务器以及应用程序/SDK 的缓存不同步。这可以通过调用 ACAccountStore 方法 renewCredentialsForAccount 来解决,这将更新操作系统对令牌状态的理解。

在 SDK 的下一次更新中,SDK 会在收到服务器响应的令牌失效时自动调用该 API。对于 SDK 的 3.1.0 版本,应用程序将需要显式调用此 API。这是一个代码示例:

ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) &&
    (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){

    NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
    id account;
    if (fbAccounts && [fbAccounts count] > 0 &&
        (account = [fbAccounts objectAtIndex:0])){

        [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
            //we don't actually need to inspect renewResult or error.
            if (error){

            }
        }];
    }
}

调用 API 的地点/时间有多种选择。最简单的地方是在应用程序启动或视图加载时伺机进行调用。这种方法的一个问题是它会导致通常不必要的网络往返。另一种选择是在会话更改通知发生时调用它,指示会话已关闭。此外,许多应用程序在应用程序启动时获取一些基本信息,例如 graph.facebook.com/me,如果是这样——在错误响应的情况下调用此方法可能是要求 iOS 更新其令牌的合理位置地位。

希望这会有所帮助!

于 2012-09-29T16:09:09.997 回答
7

我只是要贡献另一件事来检查导致我浪费了 3 个小时:如果您尝试使用非应用程序开发人员 FB 用户登录,请确保您的 FB 应用程序设置没有“沙盒”选项...也许很明显,但希望可以为其他人节省几个小时。

于 2012-11-06T11:39:13.207 回答
4

尝试按照此处的建议在 Facebook APP的设置面板中添加您的 iOS App Bundle ID(如果尚未添加)。

希望这可以帮助。

于 2012-09-28T17:34:48.920 回答
1
[FBSession openActiveSessionWithReadPermissions:nil
 allowLoginUI:YES
 completionHandler:^(FBSession *session, FBSessionState  state, NSError *error) 
    {

       switch (state) {
           case FBSessionStateOpen:
               [self presentPostOptions];
               break;

           case FBSessionStateClosed:
           case FBSessionStateClosedLoginFailed:
               [FBSession.activeSession closeAndClearTokenInformation];
               break;

           default:
               break;
       }

      }];   
于 2015-01-08T05:20:27.490 回答
1

我很确定这是一个 Facebook iOS SDK 错误(即使在 3.1.1 上),我提交了这个错误报告

在尝试使用他们的示例应用程序 Scrumptious 重现此错误时,我发现如果您使用openActiveSessionWithReadPermissions. 但是,如果您通过 请求发布权限openActiveSessionWithPublishPermissions,它将被困在com.facebook.sdk.error 5.

于 2012-10-18T04:59:51.903 回答
0

在 facebook SDK 3.7.1 我仍然有这个问题。基本上我决定在发生这种情况时从 facebook 缓存中清除令牌。像这样:

if(state == FBSessionStateClosed ) {
     [FBSession.activeSession closeAndClearTokenInformation];
}
于 2014-09-11T16:15:09.397 回答
0

Facebook 验证访问令牌时出错的简单 Swift 2+ 解决方案

// Step 1: Logout 
FBSDKLoginManager().logOut()

// Step 2: Login
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"], fromViewController: self, handler: { result, error -> Void in 

// ...

}

如果出现此错误,您必须创建新的Facebook Session,因此您必须重新登录。

于 2016-07-20T11:05:05.653 回答