我们的Facebook登录目前无效。我们收到了Facebook Developer Portal的消息:
“应用程序名称”目前可以访问Graph API v2.2,该API将到达其末尾 2017年3月27日为期2年。为确保顺利过渡, 请将所有调用迁移到Graph API v2.3或更高版本。
要检查您的应用是否会受到此升级的影响,您可以使用 版本升级工具。这将显示哪些呼叫(如果有) 受此更改影响以及更新的更换电话 版本。如果您没有看到任何电话,您的应用可能不会受到影响 这种变化。
您还可以使用我们的更改日志查看所有更改的完整列表 图谱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中为空:
[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 Dev。 Portal我们的API版本是2.3
我们测试了很多选项,没有结果:
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?
非常感谢您的帮助。
答案 0 :(得分:10)
我遇到了同样的问题,这就是我如何设法修复它并从Facebook获取电子邮件。
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);
}
}
答案 1 :(得分:0)
只需更新与OWIN相关的所有参考 最新的OWIN版本是3.1.0rc1。
这修复了登录按钮,而不是电子邮件,我无法弄清楚这些问题。
答案 2 :(得分:0)
如果由于语言包而无法更新OWIn包(我的情况),你可以
修改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()的定义类:
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; }
}