0

我正在构建一个允许用户通过 Facebook 登录的 MVC 4 网站。所有这些都像是开箱即用的魅力。

但现在我被困在从 Facebook 获取用户的生日。我已经从 Nuget 安装了最新版本的 Facebook C# SDK (6.1.4)。我已经在 Facebook 中设置了我的应用程序以请求 user_birthday 的权限。当我查看登录对话框时,预览生日在权限列表中。

当我运行我的 MVC 应用程序并通过我自己的 facebook 帐户登录时,我会在响应中得到我的生日,但是一旦我使用其他帐户登录,就不会传回生日,也没有用户可以授予我的登录对话框应用程序使用生日字段的权限。下面是我的 ExternalLoginCallback() 操作的完整代码:

[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
    AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));

    if (!result.IsSuccessful)
    {
        return RedirectToAction("ExternalLoginFailure");
    }

    // Get the Facebook access token
    if (result.ExtraData.Keys.Contains("accesstoken"))
    {
        Session["facebooktoken"] = result.ExtraData["accesstoken"];
    }

    if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
    {
        return RedirectToLocal(returnUrl);
    }

    if (User.Identity.IsAuthenticated)
    {
        // If the current user is logged in add the new account
        OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);

        return RedirectToLocal(returnUrl);
    }
    else
    {
        // User is new, ask for their desired membership name
        string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);

        ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;

        ViewBag.ReturnUrl = returnUrl;

        var client = new FacebookClient(Session["facebooktoken"].ToString());

        dynamic response = client.Get("me", new { fields = "gender, birthday" });

        return View("ExternalLoginConfirmation", 
            new RegisterExternalLoginModel 
            { 
                UserName = result.UserName, 
                FullName = result.ExtraData["name"], 
                DateOfBirth = DateTime.ParseExact(response["birthday"], "MM/dd/yyyy", CultureInfo.InvariantCulture), 
                ExternalLoginData = loginData 
            });
    }
}

我希望有人能告诉我我在这里做错了什么。我已经用谷歌搜索了两天,但不知何故我无法找到正确的答案。或者也许我只是愚蠢地理解它。

任何帮助将不胜感激。

欧文

4

2 回答 2

1

You have to make sure that you add the birthday to the scope! Default it is not grapped by the facebookAuthenticationvar fbAuthOpt = new FacebookAuthenticationOptions();

        fbAuthOpt.Scope.Add("email");
        fbAuthOpt.Scope.Add("user_birthday");
        fbAuthOpt.AppId = "";
        fbAuthOpt.AppSecret = "";
        fbAuthOpt.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
        fbAuthOpt.Provider = new FacebookAuthenticationProvider
        {
            OnAuthenticated = async context =>
            {
                context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));

                foreach (var claim in context.User)
                {
                    var claimType = string.Format("urn:facebook:{0}", claim.Key);
                    var claimValue = claim.Value.ToString();

                    if (!context.Identity.HasClaim(claimType, claimValue))
                        context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
                }

            }
        };

        app.UseFacebookAuthentication(fbAuthOpt);

Later on I grap this with "urn:facebook:birthday".

于 2014-02-28T13:00:26.757 回答
0

这篇文章有一个对我很有用的修复程序!他创建了一个自定义 facebook 提供程序,您可以在其中创建请求权限的范围,然后创建查询字符串以获取信息。

http://savvydev.com/authenticating-facebook-users-with-mvc-4-oauth-and-obtaining-scope-permissions/

于 2014-03-20T18:05:11.810 回答