Facebook SDK 3.1 – Error al validar el token de acceso

Estoy intentando hacer la transición de mi aplicación al nuevo Facebook SDK 3.1 (con soporte para autenticación iOS6).

Lo estaba funcionando bien, así que decidí eliminar la aplicación de mi lista de aplicaciones autorizadas en el sitio web de FB para probar que iOS pediría permiso de nuevo.

Ahora mi primera llamada a [FBRequest requestForMe] causa este error:

Respuesta:

 { "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 } } 

Algunos detalles:

Estoy tratando de abrir la sesión de la siguiente manera:

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

Luego me devuelven la llamada en el estado FBSessionStateOpen (en este momento iOS no ha presentado un diálogo de solicitud, ¿es de esperar)? Facebook registra esto:

 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 

Una vez que la sesión está abierta, en presentPostOptions hago esto:

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

Antes de que se vuelva a llamar el bloque de finalización anterior, se llama a mi bloque de controlador de estado principal con un estado FBSessionStateClosed . Mientras tanto, el SDK de Facebook ha registrado el error anterior.

No puedo encontrar ninguna forma de restablecer el sistema; ni realmente entiendo la causa.

¿Alguien puede por favor arrojar algo de luz?

La cuenta de Facebook en el dispositivo no está sincronizada con el servidor y con el caché de la aplicación / SDK. Esto se puede resolver llamando al método ACAccountStore renewCredentialsForAccount, que actualizará la comprensión del SO del estado del token.

En la próxima actualización del SDK, el SDK llamará automáticamente a esta API cuando reciba una respuesta del servidor que indique que un token ha dejado de ser válido. Para la revisión 3.1.0 del SDK, las aplicaciones necesitarán llamar explícitamente a esta API. Aquí hay una muestra de código:

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

Hay varias opciones para dónde / cuándo llamar a la API. El lugar más simple sería hacer la llamada oportunista al inicio de la aplicación o al cargar la vista. Un problema con este enfoque es que causará una red de ida y vuelta que a menudo es innecesaria. Otra opción es llamarlo cuando se produce una notificación de cambio de sesión, lo que indica que se ha cerrado una sesión. Además, muchas aplicaciones obtienen información básica, como graph.facebook.com/me, en el momento del lanzamiento de la aplicación, y si es así, una llamada a este método en caso de una respuesta de error puede ser un lugar razonable para pedirle a iOS que actualice su token estado.

¡Espero que esto ayude!

Voy a contribuir con algo más para verificar que me haya hecho perder 3 horas: asegúrate de que la configuración de tu aplicación FB no tenga activada la opción ‘Sandbox’ si estás intentando iniciar sesión con un usuario FB no desarrollador de aplicaciones. … Tal vez sea obvio, pero podría salvar a otros unas horas con suerte.

Intente agregar, si aún no lo hizo, su ID del paquete de aplicaciones de iOS en el panel de configuraciones de su aplicación de Facebook como se sugiere aquí .

Espero que esto ayude.

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

Estoy bastante seguro de que este es un error SDK de iOS de Facebook (incluso en 3.1.1) y archivé este informe de error .

Al tratar de reproducir este error usando su aplicación de muestra Riquísima, descubrí que te permite volver a autorizar correctamente si estás usando openActiveSessionWithReadPermissions . Sin embargo, si solicita permisos de publicación a través de openActiveSessionWithPublishPermissions , estaría bloqueado en com.facebook.sdk.error 5 .

En Facebook SDK 3.7.1 todavía tenía este problema. Básicamente, he decidido borrar el token de la memoria caché de Facebook cuando esto sucede. Me gusta esto:

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

Solución simple Swift 2+ para error de Facebook validación Token de acceso

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

Si se produce este error, debe crear una nueva sesión de Facebook , por lo que debe iniciar sesión de nuevo.