Receive Facebook Users Email at OWIN

I am learning how to work with external OWIN authentication using the default MVC template in VS 2015. I turned on the auth function on Facebook and added the email area, expecting that the user's email will be returned to Facebook after user authentication (as previously ) . However, the context is missing an email address. User JSON object and context. Email is also null.

This is the corresponding code in Startup.Auth.cs

var facebookOptions = new FacebookAuthenticationOptions { AppId = "XXXXXX", AppSecret = "XXXXXX", Provider = new FacebookAuthenticationProvider { OnAuthenticated = context => { // Retrieve the OAuth access token to store for subsequent API calls var accessToken = context.AccessToken; // Retrieve the username var facebookUserName = context.UserName; // WHY IS IT EMPTY? var facebookEmail = context.Email; // You can even retrieve the full JSON-serialized user var serializedUser = context.User; return Task.FromResult(0); } } }; facebookOptions.Scope.Add("email"); app.UseFacebookAuthentication(facebookOptions); 

Any ideas what is missing? Why is facebook email not returned?

+5
source share
1 answer

It turns out that Facebook API v 2.4 has undergone significant changes in which you need to specify the fields that you want to receive. Previously used a graph request:

 https://graph.facebook.com/v2.3/me?access_token=XXXXX 

but for performance reasons, as from FB API v2.4, you also need to specify the files that you want to receive within the scope:

 https://graph.facebook.com/v2.4/me?fields=id,name,email&access_token=XXXXX 

The Microsoft FB client implementation, by default, binds access_token to the query string as "? Access_token", which leads to a broken request (additional question mark):

https://graph.facebook.com/v2.4/me?fields=id,name,email?access_token=XXXXX

So, to fix this, we need to use a custom BackchannelHttpHandler. First, we create an endpoint class:

  public class FacebookBackChannelHandler : HttpClientHandler { protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (!request.RequestUri.AbsolutePath.Contains("/oauth")) { request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token")); } return await base.SendAsync(request, cancellationToken); } } 

And then we provide it in facebook auth options along with an explicit indication of UserInformationEndpoint:

 var facebookAuthOptions = new FacebookAuthenticationOptions { AppId = ConfigurationManager.AppSettings["FacebookAppId"], AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"], BackchannelHttpHandler = new FacebookBackChannelHandler(), UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email", Scope = { "email" } <.....> }; 

From: fooobar.com/questions/89113 / ...

+4
source

Source: https://habr.com/ru/post/1238861/


All Articles