Acceda a la dirección de correo electrónico en la API de OAuth ExternalLoginCallback de Facebook v2.4 en ASP.NET MVC 5

Con v2.3 de la API de Facebook, siempre que se establezca lo siguiente, la dirección de correo electrónico de los usuarios se devolverá en la callback a ExternalLoginCallback ;

 app.UseFacebookAuthentication(new FacebookAuthenticationOptions { AppId = "XXX", AppSecret = "XXX", Scope = { "email" } }); 

Sin embargo, cualquier aplicación que solo puede apuntar a v2.4 (lanzada el 8 de julio) ya no devuelve la dirección de correo electrónico a ExternalLoginCallback .

Creo que esto posiblemente esté relacionado con los cambios v2.4 que se enumeran aquí ;

Campos declarativos

Para tratar de mejorar el rendimiento en redes móviles, Nodos y Bordes en v2.4 requiere que solicites explícitamente los campos que necesitas para tus solicitudes GET. Por ejemplo, GET /v2.4/me/feed ya no incluye me gusta y comentarios de manera predeterminada, pero GET /v2.4/me/feed?fields=comments,likes devolverá los datos. Para obtener más detalles, consulte los documentos sobre cómo solicitar campos específicos.

¿Cómo puedo acceder a esta dirección de correo electrónico ahora?

Para resolver esto, tuve que instalar el SDK de Facebook para .NET desde nuget y consultar la dirección de correo electrónico por separado.

En el método ExternalLoginCallback , agregué un condicional para rellenar la dirección de correo electrónico desde la API Graph de Facebook;

 var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { return RedirectToAction("Login"); } // added the following lines if (loginInfo.Login.LoginProvider == "Facebook") { var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie); var access_token = identity.FindFirstValue("FacebookAccessToken"); var fb = new FacebookClient(access_token); dynamic myInfo = fb.Get("/me?fields=email"); // specify the email field loginInfo.Email = myInfo.email; } 

Y para obtener FacebookAccessToken extendí ConfigureAuth ;

 app.UseFacebookAuthentication(new FacebookAuthenticationOptions { AppId = "XXX", AppSecret = "XXX", Scope = { "email" }, Provider = new FacebookAuthenticationProvider { OnAuthenticated = context => { context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken)); return Task.FromResult(true); } } }); 

En MVC 6 (Asp.net Core 1.0), configurando FacebookAuthentication en startup.cs como este:

  app.UseFacebookAuthentication(options => { options.AppId = Configuration["Authentication:Facebook:AppId"]; options.AppSecret = Configuration["Authentication:Facebook:AppSecret"]; options.Scope.Add("email"); options.UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name"; }); 

Podría recibir el correo electrónico. Es decir:

  var info = await _signInManager.GetExternalLoginInfoAsync(); var email = info.ExternalPrincipal.FindFirstValue(ClaimTypes.Email);