Facebook SDK 3.1 – validation访问令牌时出错

我试图将我的应用程序转换到新的Facebook SDK 3.1(支持iOS6身份validation)。

我工作得很好,于是我决定从FB网站的授权应用程序列表中删除应用程序,以testingiOS会再次请求许可。

现在我第一次调用[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没有提出请求对话框,这是预期的)? Facebooklogin这个:

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

在上述完成块被callback之前,我的主要状态处理程序块被调用FBSessionStateClosed状态。 同时,Facebook SDK已经logging了上述错误。

我找不到任何方法来重置系统; 我也不明白原因。

任何人都可以摆脱一些光?

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

在SDK的下一次更新中,当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){ } }]; } } 

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

希望这有助于!

我只是要做出另一件事来检查是否浪费了3个小时:如果您尝试使用非应用程序开发者FB用户login,请确保您的FB应用程序设置没有“沙箱”选项也许很明显,但希望能够节省他人几个小时。

如果您尚未添加,请按照此处的build议在您的Facebook应用程序的设置面板中添加您的iOS App Bundle ID。

希望这可以帮助。

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

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

在尝试使用他们的示例应用程序Scrumptious重现此错误时,我发现它允许您成功地重新授权,如果您使用的是openActiveSessionWithReadPermissions 。 但是,如果您通过openActiveSessionWithPublishPermissions请求发布权限,则会卡在com.facebook.sdk.error 5

在Facebook SDK 3.7.1中,我仍然有这个问题。 基本上,我决定清除Facebookcaching中的令牌时,发生这种情况。 喜欢这个:

 if(state == FBSessionStateClosed ) { [FBSession.activeSession closeAndClearTokenInformation]; } 

简单的Swift 2+解决scheme为Facebook错误validation访问令牌

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

如果发生此错误,则必须创build新的Facebook会话 ,因此您必须重新login。