Web API facebook, email声明返回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" }
        });

在accountcontrollerregisterexternal类中,我调用以下代码:

var info = await AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer();

是这个类:

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类将使用身份验证类型cookie。每当我使用它时,它将返回null,所以在网上冲浪后,我注意到有必要添加此代码,该代码反过来将使用承载身份验证,这将导致用户名和身份不再为空的回复,从而授权。(见下图)

返回对象(用户名和登录)

但是,当我想认领邮件时,我不能这样做。无论我做什么,它总是返回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.csConfiguration(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);

我不知道为什么电子邮件一开始就没有被填充,但这种方法对我来说很有效。

最新更新