Как получить значения для первого и последнего имени Facebook, используя ASP.NET MVC 5 и OWIN?

Я знаю, что поле "Имя" предоставляется, но я бы предпочел явно получить доступ к имени и фамилии. Может кто-нибудь помочь с этим? Я все еще обнимаю ASP.Net MVC.

Ответ 1

В вашем методе Startup.Auth.cs ConfigureAuth(IAppBuilder app) установите для Facebook следующее:

var x = new FacebookAuthenticationOptions();
        x.Scope.Add("email");
        x.AppId = "*";
        x.AppSecret = "**";
        x.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);
                        string claimValue = claim.Value.ToString();
                        if (!context.Identity.HasClaim(claimType, claimValue))
                            context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));

                    }

                }
        };

        x.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
        app.UseFacebookAuthentication(x);
        /*
        app.UseFacebookAuthentication(
           appId: "*",
           appSecret: "*");
         * */

Затем используйте это для доступа к информации для входа пользователя:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

И затем следующее, чтобы получить имя:

var firstNameClaim = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name");

Ответ 2

Facebook изменил свое разрешение api. Вы можете получить дополнительную информацию об этом здесь: https://developers.facebook.com/docs/facebook-login/permissions

Требуется разрешение public_profile для имени.

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
    AppId = "appId",
    AppSecret = "key"
};
facebookAuthenticationOptions.Scope.Add("email");
facebookAuthenticationOptions.Scope.Add("public_profile");
app.UseFacebookAuthentication(facebookAuthenticationOptions);

И вы можете получить его, используя:

var loginInfo = await authenticationManager.GetExternalLoginInfoAsync();
loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:name")

authenticationManager - это экземпляр, вы можете использовать:

HttpContext.GetOwinContext().Authentication;

Ответ 3

К сожалению, этот метод больше не работает, поскольку Facebook изменил значения возвращаемого значения по умолчанию с обновлением API 2.4

Похоже, что единственный способ получить first_name и т.д. теперь - использовать API-интерфейс Facebook Graph (как это говорится в сообщениях).

Я также нашел этот пост на сайте проекта Katana, который решает эту проблему и уже отправил запрос на перенос, но он не был объединен.

Надеюсь, это немного сэкономит время;)

Ответ 4

Начиная с 2017 года, это код, который работает для меня (благодаря коду Дэвида Поксона выше). Убедитесь, что вы обновили версию 3.1.0 от Microsoft.Owin.Security.Facebook.

В Startup.Auth.cs(или Startup.cs в некоторых случаях) поместите этот код:

app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
{
    AppId = "***",
    AppSecret = "****",
    BackchannelHttpHandler = new HttpClientHandler(),
    UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name",
    Scope = { "email" },
    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);
                string claimValue = claim.Value.ToString();
                if (!context.Identity.HasClaim(claimType, claimValue))
                    context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
            }
        }
    }
});

Затем в вашем внешнем методе обратного вызова вашего контроллера добавьте этот код:

var firstName = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name").Value;

Аналогично для получения фамилии используйте приведенную выше строку и замените urn:facebook:first_name на urn:facebook:last_name

Ответ 5

 private Uri RedirectUri
        {
            get
            {
                var uriBuilder = new UriBuilder(Request.Url);
                uriBuilder.Query = null;
                uriBuilder.Fragment = null;
                uriBuilder.Path = Url.Action("FacebookCallback");
                return uriBuilder.Uri;
            }
    }

    [AllowAnonymous]
    public ActionResult Facebook()
    {
        var fb = new FacebookClient();
        var loginUrl = fb.GetLoginUrl(new
        {
            client_id = "296002327404***",
            client_secret = "4614cd636ed2029436f75c77961a8***",
            redirect_uri = RedirectUri.AbsoluteUri,
            response_type = "code",
            scope = "email" // Add other permissions as needed
        });

        return Redirect(loginUrl.AbsoluteUri);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        return View("Login");
    }
    public ActionResult FacebookCallback(string code)
    {
        var fb = new FacebookClient();
        dynamic result = fb.Post("oauth/access_token", new
        {
            client_id = "296002327404***",
            client_secret = "4614cd636ed2029436f75c77961a8***",
            redirect_uri = RedirectUri.AbsoluteUri,
            code = code
        });

        var accessToken = result.access_token;

        // Store the access token in the session for farther use
        Session["AccessToken"] = accessToken;

        // update the facebook client with the access token so 
        // we can make requests on behalf of the user
        fb.AccessToken = accessToken;

        // Get the user information
        dynamic me = fb.Get("me?fields=first_name,middle_name,last_name,id,email");
        string email = me.email;
        string firstname = me.first_name;
        string middlename = me.middle_name;
        string lastname = me.last_name;

        db.Insert_customer(firstname,email,null,null,null,null,null,null,null,null,null,null,1,1,System.DateTime.Now,1,System.DateTime.Now);

        // Set the auth cookie
        FormsAuthentication.SetAuthCookie(email, false);
        return RedirectToAction("Index", "Home");
    }

}
}

Ответ 6

Facebook изменил способ, с помощью которого Graph API возвращает значение в обновлении 2.4. Теперь вам нужно явно указать все поля, которые вы хотите вернуть.

Смотрите это примечание: facebook для разработчиков Обновление информации:

Изменения графического API в версии 2.4

В прошлом ответы от вызовов Graph API возвращали набор полей по умолчанию. Чтобы уменьшить размер полезной нагрузки и улучшить задержку на мобильных устройствах сетей мы сократили количество полей по умолчанию, возвращенных для большинство вызовов Graph API. В версии 2.4 вам необходимо декларативно перечислить поля ответа для ваших вызовов.

Чтобы получить Email, FirstName и LastName из facebook:

Сначала вам нужно установить Facebook SDK для .NET пакет nuget

Затем в вашем startup.Auth.cs измените конфигурацию аутентификации Facebook следующим образом:

     app.UseFacebookAuthentication(new FacebookAuthenticationOptions
        {
            // put your AppId and AppSecret here. I am reading them from AppSettings 
            AppId = ConfigurationManager.AppSettings["FacebookAppId"],
            AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],
            Scope = { "email" },
            Provider = new FacebookAuthenticationProvider
            {
                OnAuthenticated = context =>
                {
                    context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
                    return Task.FromResult(true);
                }
            }
        });

        // this is no longer needed
        //app.UseFacebookAuthentication(
        //   appId: ConfigurationManager.AppSettings["FacebookAppId"],
        //   appSecret: ConfigurationManager.AppSettings["FacebookAppSecret"]);

Наконец, в вашем AccountController добавьте следующий код:  Метод ExternalLoginCallback:

if (string.Equals(loginInfo.Login.LoginProvider, "facebook", StringComparison.CurrentCultureIgnoreCase))
        {
            var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie);
            var access_token = identity.FindFirstValue("FacebookAccessToken");
            var fb = new FacebookClient(access_token);

            // you need to specify all the fields that you want to get back
            dynamic myInfo = fb.Get("/me?fields=email,first_name,last_name"); 
            string email = myInfo.email;
            string firstName = myInfo.first_name;
            string lastName = myInfo.last_name;
        }

Обратитесь к facebook API Guid для получения дополнительных параметров, которые вы можете вернуть.

Ответ 7

Добавить имя и фамилию в опции facebook Scope

var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
            {
                AppId = "your app id",
                AppSecret = "your app secret",
            };

            facebookOptions.Scope.Add("email");
            facebookOptions.Scope.Add("first_name");
            facebookOptions.Scope.Add("last_name");
            return facebookOptions;