skip to Main Content

our Facebook Login is not working right now. We have received a message from Facebook Developer Portal:

“Name of app” currently has access to Graph API v2.2 which will reach the end of its
2-year lifetime on 27 March, 2017. To ensure a smooth transition,
please migrate all calls to Graph API v2.3 or higher.

To check if your app will be affected by this upgrade you can use the
Version Upgrade Tool. This will show you which calls, if any, are
affected by this change as well as any replacement calls in newer
versions. If you do not see any calls, your app may not be affected by
this change.

You can also use our changelog to see the full list of changes in all
Graph API versions.

We are using ASP.NET MVC 5, and we are using or authentication like this:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
            {
                AppId = "****",
                AppSecret = "****",
                AuthenticationType = "Facebook",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new FacebookAuthenticationProvider
                {
                    OnAuthenticated = async ctx => ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, ctx.User["email"].ToString()))
                }
            };

            facebookAuthenticationOptions.Scope.Add("email");

But today, our login info object, is null in ExternalLoginCallback:

        [HttpGet]
        [AllowAnonymous]
        [RequireHttps]
        public async Task<ActionResult> ExternalLoginCallback(string returnUrl = null)
        {
            try
            {
                var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
                if (loginInfo == null)
                {
                    return RedirectToAction("Login");
                }
... more code here...

In Facebook Dev. Portal our API Version is 2.3

We have tested many options, with no results:

Access email address in the OAuth ExternalLoginCallback from Facebook v2.4 API in ASP.NET MVC 5

Why new fb api 2.4 returns null email on MVC 5 with Identity and oauth 2?

Thank you much for the help.

3

Answers


  1. Just update all the reference related to OWIN
    The latest OWIN version is 3.1.0rc1.

    This fix the login button, NOT the email, I cannot figure out these issue.

    Login or Signup to reply.
  2. I had the same problem and here is how I managed to fix it and get the email from Facebook.

    • Update following NuGet Pacakges
      • Microsoft.Owin to version 3.1.0-rc1
      • Microsoft.Owin.Security to version 3.1.0-rc1
      • Microsoft.Owin.Security.Cookies to version 3.1.0-rc1
      • Microsoft.Owin.Security.OAuth to version 3.1.0-rc1
      • Microsoft.Owin.Security.Facebook to version 3.1.0-rc1

    Then add the following code to the Identity Startup class

    var facebookOptions = new FacebookAuthenticationOptions()
            {
                AppId = "your app id",
                AppSecret = "your app secret",
                BackchannelHttpHandler = new FacebookBackChannelHandler(),
                UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name",
                Scope = { "email" }
            };
    
            app.UseFacebookAuthentication(facebookOptions);
    

    This is the definition class for FacebookBackChannelHandler():

    using System;
    using System.Net.Http;
    
    public class FacebookBackChannelHandler : HttpClientHandler
    {
        protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            System.Threading.CancellationToken cancellationToken)
        {
            // Replace the RequestUri so it's not malformed
            if (!request.RequestUri.AbsolutePath.Contains("/oauth"))
            {
                request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token"));
            }
    
            return await base.SendAsync(request, cancellationToken);
        }
    }
    
    Login or Signup to reply.
  3. If you cant update OWIn packages because of language packages (as my case) you can

    1. Modify the Identity Startup class code:

      var facebookOptions = new FacebookAuthenticationOptions()
      {
          AppId = "your app id",
          AppSecret = "your app secret",
          BackchannelHttpHandler = new FacebookBackChannelHandler(),
          UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name",
          Scope = { "email" }
      };
      
      app.UseFacebookAuthentication(facebookOptions);
      
    2. This is the definition class for FacebookBackChannelHandler():

      public class FacebookBackChannelHandler : HttpClientHandler
      {
          protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
          {
              if (!request.RequestUri.AbsolutePath.Contains("/oauth"))
              {
                  request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token"));
              }
      
              var result = await base.SendAsync(request, cancellationToken);
              if (!request.RequestUri.AbsolutePath.Contains("/oauth"))
              {
                  return result;
              }
      
              var content = await result.Content.ReadAsStringAsync();
              var facebookOauthResponse = JsonConvert.DeserializeObject<FacebookOauthResponse>(content);
      
              var outgoingQueryString = HttpUtility.ParseQueryString(string.Empty);
              outgoingQueryString.Add(nameof(facebookOauthResponse.access_token), facebookOauthResponse.access_token);
              outgoingQueryString.Add(nameof(facebookOauthResponse.expires_in), facebookOauthResponse.expires_in + string.Empty);
              outgoingQueryString.Add(nameof(facebookOauthResponse.token_type), facebookOauthResponse.token_type);
              var postdata = outgoingQueryString.ToString();
      
              var modifiedResult = new HttpResponseMessage(HttpStatusCode.OK)
              {
                  Content = new StringContent(postdata)
              };
      
              return modifiedResult;
          }
      }
      
      private class FacebookOauthResponse
      {
          public string access_token { get; set; }
          public long expires_in { get; set; }
          public string token_type { get; set; }
      }
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search