Facebook SDK 3.1 - 验证访问令牌时出错
Posted
技术标签:
【中文标题】Facebook SDK 3.1 - 验证访问令牌时出错【英文标题】:Facebook SDK 3.1 - Error validating access token 【发布时间】:2012-09-26 11:55:31 【问题描述】:我正在尝试将我的应用转换到新的 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 记录了上述错误。
我找不到任何方法来重置系统;我也不是很了解原因。
谁能解释一下?
【问题讨论】:
我遇到了与您描述的完全相同的问题,今天刚刚更新到 3.1。即使卸载应用程序也无济于事 我没有尝试卸载,因为我特别不想做一些可能使它重新开始工作的事情 :) 我真的想找到一个程序化的解决方案,这样我的用户就不会得到卡在了这个位置。无论如何,有趣的是它并不能解决问题。 仅在 iOS6 设备/模拟器中运行时会发生这种情况吗?在 iOS5 上能用吗? 嗨。这发生在在真实设备上运行的 iOS6 上。在这个阶段我还没有测试过其他任何东西。请注意,在我从 Facebook 删除应用程序的权限之前,它一直运行良好,所以我认为这让 iPhone 的内部状态一团糟,我不知道如何重置它。至少可以说令人沮丧 - 我的用户正在等待更新。 正如 tarmes 在真实设备中所说的相同问题。在 iOS5 上它可以工作,因为如果你从 Facebook 删除应用程序权限,你只需要重新授权应用程序(这样你就会被重定向到 safari 或 fb 应用程序,你只需要再次允许应用程序,正如预期的那样) 【参考方案1】:设备上的 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 更新其令牌的合理位置地位。
希望这会有所帮助!
【讨论】:
我们正在开发一个 dot 版本,修复了有限数量的错误。应该不会太远。 对于信息,我可以确认这确实解决了问题。现在我正在等待 SDK 更新,以便可以在正确的地方完成。 嗨杰森。我已经安装了 3.1.1 并删除了上面的临时修复。不幸的是,新的 SDK 并没有解决这个问题。我已经找到了问题 - 我们可以在某个地方讨论这个问题吗? @JasonClark - 我正在使用 3.1.1 并遇到各种相关问题。一种特殊情况是,如果用户从 iOS 设置中删除他们的 FB 帐户,则应用程序/SDK 仍然认为他们拥有有效的令牌。并且令牌可能是有效的,但如果用户从设置中删除了他们的帐户,继续使用它似乎是错误的。如果他们随后在 iOS 设置中添加不同的 FB 帐户会怎样 - 应用程序无法知道如何选择并使用它而不是它拥有的缓存会话。 在 SDK 3.7.1 上还是有这个问题【参考方案2】:我只是要贡献另一件事来检查导致我浪费了 3 个小时: 如果您尝试使用非应用程序开发人员 FB 用户登录,请确保您的 FB 应用程序设置没有“沙盒”选项... 也许很明显,但希望可以为其他人节省几个小时。
【讨论】:
【参考方案3】:尝试在 Facebook APP 的 settings panel 中添加您的 iOS App Bundle ID(如果尚未添加),如建议的 here。
希望这会有所帮助。
【讨论】:
嗨。我刚刚仔细检查了所有输入是否正确 - 是的,所以这不是问题。 我遇到了同样的问题,并在它工作后立即进行了检查。 证明。这当然有帮助!【参考方案4】:[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;
];
【讨论】:
【参考方案5】:我很确定这是一个 Facebook iOS SDK 错误(即使在 3.1.1 上),我提交了this bug report。
在尝试使用他们的示例应用 Scrumptious 重现此错误时,我发现如果您使用 openActiveSessionWithReadPermissions
,它可以让您成功重新授权。但是,如果您通过openActiveSessionWithPublishPermissions
请求发布权限,则会卡在com.facebook.sdk.error 5
。
【讨论】:
我没有仔细阅读documentation。您必须先调用 openActiveSessionWithRead,然后再写入。看起来你不能从 openActiveSessionWithPublishPermissions 开始..【参考方案6】:在 facebook SDK 3.7.1 中我仍然遇到这个问题。基本上我决定在发生这种情况时从 facebook 缓存中清除令牌。像这样:
if(state == FBSessionStateClosed )
[FBSession.activeSession closeAndClearTokenInformation];
【讨论】:
【参考方案7】:简单的 Swift 2+ 解决方案用于 Facebook 验证访问令牌时出错
// Step 1: Logout
FBSDKLoginManager().logOut()
// Step 2: Login
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"], fromViewController: self, handler: result, error -> Void in
// ...
如果出现此错误,您必须创建新的Facebook Session,因此您必须重新登录。
【讨论】:
以上是关于Facebook SDK 3.1 - 验证访问令牌时出错的主要内容,如果未能解决你的问题,请参考以下文章
用于Azure B2C acces令牌的Exchange Facebook SDK acces令牌
使用 Facebook 令牌的 Firebase Unity SDK 身份验证
从 Facebook Graph iOS SDK 解密或解码 Facebook 访问令牌