Web API facebook,电子邮件声明 returns null
Web API facebook, email claim returns null
代码如下
启动授权:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "xxx",
AppSecret = "xxx",
BackchannelHttpHandler = new FacebookBackChannelHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location",
Scope = { "email" }
});
在帐户控制器 RegisterExternal class 中,我调用以下内容:
var info = await AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer();
这是哪个class:
private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
{
ExternalLoginInfo loginInfo = null;
var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);
if (result != null && result.Identity != null)
{
var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
if (idClaim != null)
{
loginInfo = new ExternalLoginInfo()
{
DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value),
};
}
}
return loginInfo;
}
这是因为默认情况下 RegisterExternal class 将使用身份验证类型 cookie。每当我使用它时,它都会 return null,所以在网上冲浪后我注意到有必要添加这段代码,这反过来将使用承载进行身份验证,这将导致用户名和身份的回复不再为空,因此被授权。 (见下图)
Return object (username and login)
但是,当我想领取电子邮件时,我不能这样做。无论我做什么,它总是 return null。
我 运行 遇到了同样的问题,并通过使用 Facebook nuget 包获取额外字段解决了这个问题。
在我的应用程序中,我实现了 FacebookAuthenticationProvider
并使用以下内容覆盖了 Authenticated(...)
方法:
public class FacebookAuthProvider : FacebookAuthenticationProvider
{
public override Task Authenticated(FacebookAuthenticatedContext context)
{
var accessTokenClaim = new Claim("ExternalAccessToken", context.AccessToken, "urn:facebook:access_token");
context.Identity.AddClaim(accessTokenClaim);
var extraClaims = GetAdditionalFacebookClaims(accessTokenClaim);
context.Identity.AddClaim(new Claim(ClaimTypes.Email, extraClaims.First(k => k.Key == "email").Value.ToString()));
context.Identity.AddClaim(new Claim("Provider", context.Identity.AuthenticationType));
context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Identity.FindFirstValue(ClaimTypes.Name)));
var userDetail = context.User;
var link = userDetail.Value<string>("link") ?? string.Empty;
context.Identity.AddClaim(new Claim("link", link));
context.Identity.AddClaim(new Claim("FacebookId", userDetail.Value<string>("id")));
return System.Threading.Tasks.Task.FromResult(0);
}
private static JsonObject GetAdditionalFacebookClaims(Claim accessToken)
{
var fb = new FacebookClient(accessToken.Value);
return fb.Get("me", new { fields = new[] { "email", "first_name", "last_name" } }) as JsonObject;
}
}
我的 Startup.cs
在 Configuration(IAppBuilder app)
内有这个:
FacebookAuthOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
AppId = "YOUR APP ID",
AppSecret = "YOUR APP SECRET",
Microsoft.Owin.PathString("/Account/ExternalCallBack"), // whatever your external callback url is
Provider = new FacebookAuthProvider()
};
FacebookAuthOptions.Scope.Add("email");
app.UseFacebookAuthentication(FacebookAuthOptions);
我不知道为什么电子邮件没有首先被填充,但这种方法对我有用。
代码如下
启动授权:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "xxx",
AppSecret = "xxx",
BackchannelHttpHandler = new FacebookBackChannelHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location",
Scope = { "email" }
});
在帐户控制器 RegisterExternal class 中,我调用以下内容:
var info = await AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer();
这是哪个class:
private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
{
ExternalLoginInfo loginInfo = null;
var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);
if (result != null && result.Identity != null)
{
var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
if (idClaim != null)
{
loginInfo = new ExternalLoginInfo()
{
DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value),
};
}
}
return loginInfo;
}
这是因为默认情况下 RegisterExternal class 将使用身份验证类型 cookie。每当我使用它时,它都会 return null,所以在网上冲浪后我注意到有必要添加这段代码,这反过来将使用承载进行身份验证,这将导致用户名和身份的回复不再为空,因此被授权。 (见下图)
Return object (username and login)
但是,当我想领取电子邮件时,我不能这样做。无论我做什么,它总是 return null。
我 运行 遇到了同样的问题,并通过使用 Facebook nuget 包获取额外字段解决了这个问题。
在我的应用程序中,我实现了 FacebookAuthenticationProvider
并使用以下内容覆盖了 Authenticated(...)
方法:
public class FacebookAuthProvider : FacebookAuthenticationProvider
{
public override Task Authenticated(FacebookAuthenticatedContext context)
{
var accessTokenClaim = new Claim("ExternalAccessToken", context.AccessToken, "urn:facebook:access_token");
context.Identity.AddClaim(accessTokenClaim);
var extraClaims = GetAdditionalFacebookClaims(accessTokenClaim);
context.Identity.AddClaim(new Claim(ClaimTypes.Email, extraClaims.First(k => k.Key == "email").Value.ToString()));
context.Identity.AddClaim(new Claim("Provider", context.Identity.AuthenticationType));
context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Identity.FindFirstValue(ClaimTypes.Name)));
var userDetail = context.User;
var link = userDetail.Value<string>("link") ?? string.Empty;
context.Identity.AddClaim(new Claim("link", link));
context.Identity.AddClaim(new Claim("FacebookId", userDetail.Value<string>("id")));
return System.Threading.Tasks.Task.FromResult(0);
}
private static JsonObject GetAdditionalFacebookClaims(Claim accessToken)
{
var fb = new FacebookClient(accessToken.Value);
return fb.Get("me", new { fields = new[] { "email", "first_name", "last_name" } }) as JsonObject;
}
}
我的 Startup.cs
在 Configuration(IAppBuilder app)
内有这个:
FacebookAuthOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
AppId = "YOUR APP ID",
AppSecret = "YOUR APP SECRET",
Microsoft.Owin.PathString("/Account/ExternalCallBack"), // whatever your external callback url is
Provider = new FacebookAuthProvider()
};
FacebookAuthOptions.Scope.Add("email");
app.UseFacebookAuthentication(FacebookAuthOptions);
我不知道为什么电子邮件没有首先被填充,但这种方法对我有用。