我正在开发一个ASP.NET MVC应用程序。在我的应用程序中,我需要向用户提供Faccebook Login服务。此外,我需要从Facebook检索用户电子邮件并存储在数据库中。
我正在使用Visual Studio 2013和ASP.NET MVC5。我的Facebook登录方法运行正常。但是当我从Facebook检索电子邮件时,它给了我null异常。我的externalLoginCallback方法如下:
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var result = await AuthenticationManager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);
if (result == null || result.Identity == null)
{
return RedirectToAction("Login");
}
var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
if (idClaim == null)
{
return RedirectToAction("Login");
}
var login = new UserLoginInfo(idClaim.Issuer, idClaim.Value);
var name = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", "");
//retrieving email from facebook here
var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;//this line is throwing null exception
.
.
.
}
我评论了我的代码中出错的地方。
这就是我在Startup.Auth.cs中配置Facebook的方式
var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
AppId = "x",
AppSecret = "y"
};
facebookAuthenticationOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookAuthenticationOptions);
我也尝试过这样:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "x",
AppSecret = "y",
Scope = { "email" },
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
return Task.FromResult(true);
}
}
});
两者都不起作用。我的代码有什么问题,我该如何解决?
你可以试试这个:
var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
AppId = "xxxxxxx",
AppSecret = "xxxxxx",
BackchannelHttpHandler = new FacebookBackChannelHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location"
};
然后定义这个类:
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 response = await base.SendAsync(request, cancellationToken);
return response;
}
}
最后,您可以通过在帐户控制器中的“ExternalLoginCallback”方法中执行以下操作来获取电子邮件(和first_name,last_name,location):
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("LoginRegister");
}
// GET MAIL AND NAME
var email = loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email).Value;
var name= loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;