如何使用ASP.Net核心身份从登录用户检索Facebook个人资料图片?

时间:2017-08-24 07:39:56

标签: c# facebook-graph-api asp.net-core asp.net-identity facebook-oauth

我有一个可行的解决方案,但我想知道这是否是正确的方法。这是我到目前为止所得到的。

我正在使用ASP.Net Core 1.1.2和ASP.NET Core Identity 1.1.2。

Startup.cs 中的重要部分如下所示:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        //...
        app.UseFacebookAuthentication(new FacebookOptions
        {
            AuthenticationScheme = "Facebook",
            AppId = Configuration["ExternalLoginProviders:Facebook:AppId"],
            AppSecret = Configuration["ExternalLoginProviders:Facebook:AppSecret"]
        });
    }

FacebookOptions与Microsoft.AspNetCore.Authentication.Facebook nuget package。

AccountController.cs 中的回调函数如下所示:

    [HttpGet]
    [AllowAnonymous]
    public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
    {
        //... SignInManager<User> _signInManager; declared before
        ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
        SignInResult signInResult = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);

        byte[] thumbnailBytes = null;

        if (info.LoginProvider == "Facebook")
        {
            string nameIdentifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
            string thumbnailUrl = $"https://graph.facebook.com/{nameIdentifier}/picture?type=large";
            using (HttpClient httpClient = new HttpClient())
            {
                thumbnailBytes = await httpClient.GetByteArrayAsync(thumbnailUrl);
            }
        }
        //...
    }

所以这段代码工作得很好但是,如前所述,这是正确的方法(技术上,而不是基于意见的)吗?

4 个答案:

答案 0 :(得分:3)

要从Facebook获取个人资料图片,您需要配置Facebook选项并从OAuth订阅OnCreatingTicket事件。

services.AddAuthentication().AddFacebook("Facebook", options =>
{

    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    options.ClientId = configuration.GetSection("ExternalLogin").GetSection("Facebook").GetSection("ClientId").Value;
    options.ClientSecret = configuration.GetSection("ExternalLogin").GetSection("Facebook").GetSection("ClientSecret").Value;
    options.Fields.Add("picture");
    options.Events = new OAuthEvents
    {
        OnCreatingTicket = context =>
        {
            var identity = (ClaimsIdentity)context.Principal.Identity;
            var profileImg = context.User["picture"]["data"].Value<string>("url");
            identity.AddClaim(new Claim(JwtClaimTypes.Picture, profileImg));
            return Task.CompletedTask;
        }
    };
});

答案 1 :(得分:1)

在asp.net core 3.1中,我通过使用身份验证完成后返回的访问令牌直接调用Facebook API来完成此操作。 过程如下:

在控制器方法中,您可以挑战。

        var auth = await Request.HttpContext.AuthenticateAsync("Facebook");

这会将用户重定向到浏览器中的Facebook登录。

如果身份验证成功,即:auth.Succeeded && auth.Principal.Identities.Any(id => id.IsAuthenticated) && ! string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")

检索提供的身份验证令牌facebook:auth.Properties.GetTokenValue("access_token")

然后使用令牌手动获取用户的个人资料图片,如下所示:

    public async Task<string> GetFacebookProfilePicURL(string accessToken)
    {
        using var httpClient = new HttpClient();
        var picUrl = $"https://graph.facebook.com/v5.0/me/picture?redirect=false&type=large&access_token={accessToken}";
        var res = await httpClient.GetStringAsync(picUrl);
        var pic = JsonConvert.DeserializeAnonymousType(res, new { data = new PictureData() });
        return pic.data.Url;
    }

其中PictureData只是一个类,代表来自Facebook的graph API的响应以及有关图片的所有信息;高度,宽度,网址等。

答案 2 :(得分:0)

我仅使用标识符从图api获取图像

$"https://graph.facebook.com/{identifier}/picture?type=large";

答案 3 :(得分:0)

还可以使用自定义声明动作将json用户内容映射到声明(要使用的声明类型取决于您)。因此,图像url将被添加到Claims集合中,无需OAuthEvents(如果您不需要将其用于其他目的)。

.AddFacebook("FbCustom", x =>
        {
            x.AppId = settings.FacebookAppId;
            x.AppSecret = settings.FacebookSecret;
            x.Scope.Add("email");
            x.Scope.Add("user_hometown");
            x.Scope.Add("user_birthday");
            x.Fields.Add("birthday");
            x.Fields.Add("picture");
            x.Fields.Add("name");
            x.Fields.Add("email");
            //HERE IS CUSTOM A MAPPING
            x.ClaimActions.MapCustomJson(CustomClaimTypes.AvatarUrl, 
            json => json.GetProperty("picture").GetProperty("data").GetProperty("url").GetString());
            
        })