版本作废:Facebook Graph API v2.2

5
我们的Facebook登录目前无法使用。我们从Facebook Developer Portal收到了一条消息:

“应用名称”目前可以访问Graph API V2.2版本,该版本的生命周期将于2017年3月27日结束。为确保平稳过渡,请将所有调用迁移到Graph API V2.3或更高版本。

要检查您的应用程序是否会受到此升级的影响,可以使用版本升级工具。这将向您显示哪些调用(如果有)受此更改影响以及在较新版本中的任何替代调用。如果您没有看到任何调用,则可能不会受此更改的影响。

您还可以使用我们的更新日志来查看所有Graph API版本中的完整更改列表。

我们正在使用ASP.NET MVC 5,并且我们的认证是这样的:
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");

但是今天,在ExternalLoginCallback中,我们的登录信息对象为null:
        [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...

在Facebook开发者门户中,我们的API版本是2.3。

我们尝试了许多选项,但没有结果:

如何在ASP.NET MVC 5中从Facebook v2.4 API的OAuth ExternalLoginCallback中访问电子邮件地址

为什么新的fb api 2.4在MVC 5中使用Identity和oauth 2时返回null电子邮件?

非常感谢您的帮助。


1
在这里查看解决方案:https://dev59.com/zmEh5IYBdhLWcg3wdzaR,sammy34的答案。 - Marc Hägele
@MarcHägele 谢谢您,跟随您的链接后,由于sammy34的答案,我终于解决了我的问题。 - Alisson Reinaldo Silva
3个回答

10

我曾经遇到同样的问题,以下是我是如何解决它并从Facebook获取电子邮件的。

  • 更新以下NuGet软件包:
    • Microsoft.Owin 版本为 3.1.0-rc1
    • Microsoft.Owin.Security 版本为 3.1.0-rc1
    • Microsoft.Owin.Security.Cookies 版本为 3.1.0-rc1
    • Microsoft.Owin.Security.OAuth 版本为 3.1.0-rc1
    • Microsoft.Owin.Security.Facebook 版本为 3.1.0-rc1

然后将以下代码添加到Identity Startup类中。

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

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

这绝对是我实现的完整解决方案,很棒。 - chemitaxis
这太不可思议了...OWIN团队太糟糕了...我会尝试的,稍后再回来告诉你,我的应用因此死了。 - Sebastián Rojas
@user3012760需要更新软件包吗?因为西班牙语语言的RC1软件包仍然不可用... - Sebastián Rojas

0

如果您因语言包无法更新OWIn包(与我的情况类似),您可以:

  1. 修改Identity Startup类代码:

    var facebookOptions = new FacebookAuthenticationOptions()
    {
        AppId = "你的应用程序ID",
        AppSecret = "你的应用程序密钥",
        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. 这是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; }
    }
    

0

只需更新与OWIN相关的所有引用即可。 最新的OWIN版本是3.1.0rc1。

这修复了登录按钮,但未解决电子邮件问题,我无法弄清楚这些问题。


它专门修复了登录按钮,因为Facebook已将身份验证令牌请求的响应类型更新为JSON,而MS Owin 3.0.1无法处理。 - J. Steen
1
我已经更新到rc1并且问题已经解决。但是我需要插入一个答案的代码。 - chemitaxis
好的,我也会关注这个。 - HolloW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接