为什么新的FB API 2.4返回空电子邮件MVC的5与身份和OAuth 2? [英] Why new fb api 2.4 returns null email on MVC 5 with Identity and oauth 2?

查看:209
本文介绍了为什么新的FB API 2.4返回空电子邮件MVC的5与身份和OAuth 2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

曾经工作完美的一切,直到FB升级她的API为 2.4 (我不得不 2.3 在我的previous项目)。

今天,当我添加FB上开发新的应用程序,我用API 2.4得到它。

问题:现在我从FB空电子邮件( loginInfo.email = NULL

当然,我检查了用户电子邮件公共状态FB上的个人资料,

和我走到了 LOGININFO 对象,但没有发现任何其他的电子邮件地址。

和我的谷歌,但没有找到任何答案。

请任何帮助..我在那种失去了..

谢谢,

我原来的code(其中工作的2.3 API):

在AccountController.cs:

  //
// GET:/帐号/ ExternalLoginCallback
[使用AllowAnonymous]
公共异步任务<&的ActionResult GT; ExternalLoginCallback(字符串RETURNURL)
{
    VAR LOGININFO =等待AuthenticationManager.GetExternalLoginInfoAsync();
    如果(LOGININFO == NULL)
    {
        返回RedirectToAction(登录);
    }
    //一种方式来获得有关日志的用户FB的详细信息:
    // VAR firstNameClaim = loginInfo.ExternalIdentity.Claims.First(C => c.Type ==瓮:Facebook的:FIRST_NAME); < - 只有在工作2.3
    // VAR firstNameClaim = loginInfo.ExternalIdentity.Claims.First(C => c.Type ==瓮:Facebook的:名称); < - 适用于2.4 API    // SIGN在这个外部登录提供用户,如果用户已经有一个登录
    VAR的结果=等待SignInManager.ExternalSignInAsync(LOGININFO,isPersistent:假);
    开关(结果)
    {
        案例SignInStatus.Success:
            返回RedirectToLocal(RETURNURL);
        案例SignInStatus.LockedOut:
            返回视图(锁定);
        案例SignInStatus.RequiresVerification:
            返回RedirectToAction(发送code,新的{RETURNURL = RETURNURL,与rememberMe = FALSE});
        案例SignInStatus.Failure:
        默认:
            //如果用户没有一个帐户,然后提示用户创建一个帐户
            ViewBag.ReturnUrl = RETURNURL;
            ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
            返回视图(ExternalLoginConfirmation,新ExternalLoginConfirmationViewModel {电子邮件= loginInfo.Email}); //< ---不工作。 loginInfo.Email IS NULL
    }
}

在Startup.Auth.cs:

  Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions fbOptions =新Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
    {
        的AppId = System.Configuration.ConfigurationManager.AppSettings.Get(FacebookAppId),
        AppSecret = System.Configuration.ConfigurationManager.AppSettings.Get(FacebookAppSecret),
    };
    fbOptions.Scope.Add(电子邮件);
    fbOptions.Provider =新Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
    {
        OnAuthenticated =(上下文)=>
        {
            context.Identity.AddClaim(新System.Security.Claims.Claim(FacebookAccessToken,context.AccessToken));
            的foreach(VAR索赔context.User)
            {
                VAR claimType =的String.Format(瓮:Facebook的:{0},claim.Key);
                字符串claimValue = claim.Value.ToString();
                如果(!context.Identity.HasClaim(claimType,claimValue))
                    context.Identity.AddClaim(新System.Security.Claims.Claim(claimType,claimValue,XmlSchemaString,脸谱));            }
            返回System.Threading.Tasks.Task.FromResult(0);
        }
    };
    fbOptions.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
    app.UseFacebookAuthentication(fbOptions);


解决方案

武士刀线程我设计了以下内容:

更改 FacebookAuthenticationOptions 包括 BackchannelHttpHandler UserInformationEndpoint 如下所示。确保包括你想要和需要为您实现字段的名称。

  VAR facebookOptions =新FacebookAuthenticationOptions()
{
                的AppId =*,
                AppSecret =*,
                BackchannelHttpHandler =新FacebookBackChannelHandler()
                UserInformationEndpoint =htt​​ps://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location
}

然后创建一个自定义的 FacebookBackChannelHandler 将拦截请求给Facebook,并根据需要修复错误的URL。

 公共类FacebookBackChannelHandler:HttpClientHandler
{
    保护覆盖异步System.Threading.Tasks.Task< Htt的presponseMessage> SendAsync(HTT prequestMessage要求,System.Threading.CancellationToken的CancellationToken)
    {
        //更换RequestUri所以它不是畸形
        如果(!request.RequestUri.AbsolutePath.Contains(/ OAuth的))
        {
            request.RequestUri =新的URI(request.RequestUri.AbsoluteUri.Replace(的access_token?,与& ACCESS_TOKEN));
        }        返回等待base.SendAsync(请求的CancellationToken);
    }
}

一个有益的补充将是检查库的版本3.0.1,如果当它改变抛出异常。这样,如果一个人升级或修复此问题已被释放后,更新的NuGet包你就会知道。

Everything used to work perfect until fb upgraded her api to 2.4 (I had 2.3 in my previous project).

Today when I add a new application on fb developers I get it with api 2.4.

The problem: Now I get null email from fb (loginInfo.email = null).

Of course I checked that the user email is in public status on fb profile,

and I went over the loginInfo object but didn't find any other email address.

and I google that but didn't find any answer.

please any help.. I 'm kind of lost..

Thanks,

My original code (which worked on 2.3 api):

In the AccountController.cs:

//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
    var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
    if (loginInfo == null)
    {
        return RedirectToAction("Login");
    }
    //A way to get fb details about the log-in user: 
    //var firstNameClaim = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name");  <--worked only on 2.3
    //var firstNameClaim = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:name"); <--works on 2.4 api

    // Sign in the user with this external login provider if the user already has a login
    var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
        case SignInStatus.Failure:
        default:
            // If the user does not have an account, then prompt the user to create an account
            ViewBag.ReturnUrl = returnUrl;
            ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
            return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });  //<---DOESN'T WORK. loginInfo.Email IS NULL
    }
}

In the Startup.Auth.cs:

    Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions fbOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
    {
        AppId = System.Configuration.ConfigurationManager.AppSettings.Get("FacebookAppId"),
        AppSecret = System.Configuration.ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
    };
    fbOptions.Scope.Add("email");
    fbOptions.Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
    {
        OnAuthenticated = (context) =>
        {
            context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
            foreach (var claim in context.User)
            {
                var claimType = string.Format("urn:facebook:{0}", claim.Key);
                string claimValue = claim.Value.ToString();
                if (!context.Identity.HasClaim(claimType, claimValue))
                    context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));

            }
            return System.Threading.Tasks.Task.FromResult(0);
        }
    };
    fbOptions.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
    app.UseFacebookAuthentication(fbOptions);

解决方案

Taken from a Katana Thread I devised the following:

Change the FacebookAuthenticationOptions to include BackchannelHttpHandler and UserInformationEndpoint as seen below. Make sure to include the names of the fields you want and need for your implementation.

var facebookOptions = new FacebookAuthenticationOptions()
{
                AppId = "*",
                AppSecret = "*",
                BackchannelHttpHandler = new FacebookBackChannelHandler(),
                UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location"
}

Then create a custom FacebookBackChannelHandler that will intercept the requests to Facebook and fix the malformed url as needed.

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

One useful addition would be to check for the version 3.0.1 of the library and throw an exception if and when it changes. That way you'll know if someone upgrades or updates the NuGet package after a fix for this problem has been released.

这篇关于为什么新的FB API 2.4返回空电子邮件MVC的5与身份和OAuth 2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆