iOS的Facebook的SDK 4.0login错误代码304

我刚刚更新了Facebook SDK 4.0版本

并根据使用自定义login用户界面的教程

-(IBAction)facebookLoginClick:(id)sender { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; [login logInWithReadPermissions:@[@"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { // Process error } else if (result.isCancelled) { // Handle cancellations } else { // If you ask for multiple permissions at once, you // should check if specific permissions missing if ([result.grantedPermissions containsObject:@"email"]) { // Do work } } }]; } 

但结果总是零,错误代码是304, 我错过了什么?

我有一个类似的问题。

在初始化FBSDKLoginManager我添加了一行来清除数据和(Facebook)令牌:

 FBSDKLoginManager *loginmanager= [[FBSDKLoginManager alloc]init]; [loginmanager logOut]; 

希望这可以帮助。


因此,正如OP所要求的,“我错过了什么”?

是的,随处可见的以下标准示例代码简直是错误的:

 -(IBAction)facebookLoginClick:(id)sender { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; ---- ONE MAGIC LINE OF CODE IS MISSING HERE ---- [login logInWithReadPermissions:@[@"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) {...} else if (result.isCancelled) {...} else { // (NB for multiple permissions, check every one) if ([result.grantedPermissions containsObject:@"email"]) { NSLog(@"%@",result.token); } } }]; } 

你必须这样做:

 -(IBAction)facebookLoginClick:(id)sender { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; [login logOut]; //ESSENTIAL LINE OF CODE [login logInWithReadPermissions:@[@"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) {...} else if (result.isCancelled) {...} else { // (NB for multiple permissions, check every one) if ([result.grantedPermissions containsObject:@"email"]) { NSLog(@"%@",result.token); } } }]; } 

否则,非常简单,如果用户碰巧更改设备上的FB帐户 ,则该应用程序将不起作用 。 (除非他们出于某种原因重新安装应用程序!)

再次 – 如果用户碰巧更改FB帐户,上面stream行的示例代码根本不起作用 (应用程序进入无限循环)。 必须进行logOut调用。

当我将Facebook AppID(在Info.plist文件中)从testingFacebook应用切换到生产Facebook应用时,发生在我身上。 如果您的应用程序将Facebook令牌发送给生成JWT的服务器,则Facebook SDK仍会保留fbToken( FBSDKAccessToken.currentAccessToken() ),除非它被告知将其删除。 当用户注销应用程序时,也可能会发生这种情况,注销API请求会将用户注销并重置您的JWT。 但是即使在发送注销API请求之前,客户端也需要告诉FBSDKLoginManager实例注销。

 if let currentAccessToken = FBSDKAccessToken.currentAccessToken() where currentAccessToken.appID != FBSDKSettings.appID() { loginManager.logOut() } 

我有这个,当iOS应用程序运行时,在Xcode中更改FB应用程序细节时发生。 您需要从设备中删除应用程序,然后重新发布新的FB应用程序设置。 只是重新编译是不够的,以清除旧的FB设置

您可以使用下面的代码来解决您的问题:

 [FBSDKAccessToken refreshCurrentAccessToken:^(FBSDKGraphRequestConnection *connection, id result, NSError *error){} 

根据文档,304 FBSDKLoginUserMismatchErrorCode “表示由于用户已经改变而未能请求新的权限”

在@ Adrian999提到的场景中有意义。

其实,原因很简单,你可以尝试下面的步骤轻松地重现这个错误代码。

Facebooklogin失败 ”可能有两个原因:

  1. 你从facebook上获得用户信息失败。
  2. 你从Facebook成功获取用户信息,但上传到自己的服务器失败。

FBSDKLoginManager.m的代码是:

 - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult { FBSDKGraphRequest *requestMe = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:nil tokenString:loginResult.token.tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [requestMe startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { NSString *actualID = result[@"id"]; if ([currentToken.userID isEqualToString:actualID]) { [FBSDKAccessToken setCurrentAccessToken:loginResult.token]; [self invokeHandler:loginResult error:nil]; } else { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [FBSDKInternalUtility dictionary:userInfo setObject:error forKey:NSUnderlyingErrorKey]; NSError *resultError = [NSError errorWithDomain:FBSDKLoginErrorDomain code:FBSDKLoginUserMismatchErrorCode userInfo:userInfo]; [self invokeHandler:nil error:resultError]; } }]; } 

currentToken.userID不等于actualIDFBSDKLoginUserMismatchErrorCode会抛出。

现在,当用户AloginFacebook失败时,这个问题会再次出现,但是失败后你没有[FacebookSDKManager logOut] ,应用会caching用户A的accessToken,然后用户A将facebook账户更改为用户B, B再次loginFacebook,它会重新出现这个问题。

我也被困在这个问题上了一段时间。 然后在.h文件和.m文件的viewDidLoad中为FBSDKLoginManager创build对象,初始化它并设置注销属性。

  _fbLogin= [[FBSDKLoginManager alloc]init]; [_fbLogin logOut]; 

这帮助了我,也希望能帮助你。 祝一切顺利。

谢谢

Swift 3.0

 func loginWithFacebook { let loginManager = FBSDKLoginManager() if let currentAccessToken = FBSDKAccessToken.current(), currentAccessToken.appID != FBSDKSettings.appID() { loginManager.logOut() } loginManager.logIn(withReadPermissions: ["public_profile","email"], from: self, handler: { (result, error) in if error != nil { print("error\(String(describing: error))") } else if (result?.isCancelled)! { } else { print(FBSDKAccessToken.current()) } }) } 

单一login

我还发现,如果您的应用程序不需要单点login (即多个用户将创build内容并从一个设备共享的应用程序),则会发生此问题。

您可以在应用设置中更改单点loginhttps://developers.facebook.com/apps/your-app-id/settings/ 。

检查您的FBSession的状态:

 isOpen Indicates whether the session is open and ready for use. @property (readonly) BOOL isOpen; Declared In: FBSession.h 

https://developers.facebook.com/docs/reference/ios/3.0/class/FBSession/

304表示没有任何变化。 也许你已经authentication了,所以没有304,没有任何变化。