简体   繁体   English

如何使用 ASP.Net Core Identity 从登录用户处检索 Facebook 个人资料图片?

[英]How to retrieve Facebook profile picture from logged in user with ASP.Net Core Identity?

I've got a working solution for this, but I'm wondering if this is the correct way to do it.我有一个可行的解决方案,但我想知道这是否是正确的方法。 Here's what I got so far.这是我到目前为止所得到的。

I'm using ASP.Net Core 1.1.2 with ASP.NET Core Identity 1.1.2.我将 ASP.Net Core 1.1.2 与 ASP.NET Core Identity 1.1.2 一起使用。

The important part in Startup.cs looks like this: 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"]
        });
    }

FacebookOptionscomes with Microsoft.AspNetCore.Authentication.Facebook nuget package. FacebookOptions 附带 Microsoft.AspNetCore.Authentication.Facebook nuget 包。

The callback function in AccountController.cs looks like this: 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);
            }
        }
        //...
    }

So this code is working absolutely fine but, as mentioned before, is this the correct way (technically, not opinion-based) to do it?所以这段代码工作得很好,但是,如前所述,这是正确的方法(从技术上讲,不是基于意见)吗?

To get profile picture from Facebook, you need to configure Facebook options and subscribe at OnCreatingTicket event from OAuth.要从 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;
        }
    };
});

In ASP.NET Core 3.0 there was a breaking change in OAuthCreatingTicketContext, see https://docs.microsoft.com/en-US/dotnet/core/compatibility/2.2-3.0在 ASP.NET Core 3.0 中,OAuthCreatingTicketContext 发生了重大变化,请参阅https://docs.microsoft.com/en-US/dotnet/core/compatibility/2.2-3.0

I changed我变了

var profileImg = context.User["picture"]["data"].Value<string>("url");

to

var profileImg = context.User.GetProperty("picture").GetProperty("data").GetProperty("url").ToString();

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

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

in asp.net core 3.1, I did this by calling Facebook APIs directly with the access token returned when the authentication is done.在 asp.net core 3.1 中,我通过使用完成身份验证时返回的访问令牌直接调用 Facebook API 来做到这一点。 Here is the process:这是过程:

In a controller method, you can challenge.在控制器方法中,您可以挑战。

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

This will redirect the user to Facebook login in the browser.这会将用户重定向到浏览器中的 Facebook 登录。

If the authentication succeeds, that is: auth.Succeeded && auth.Principal.Identities.Any(id => id.IsAuthenticated) && ! string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")如果认证成功,即: auth.Succeeded && auth.Principal.Identities.Any(id => id.IsAuthenticated) && ! string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token") auth.Succeeded && auth.Principal.Identities.Any(id => id.IsAuthenticated) && ! string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")

Retrieve the authentication token facebook provided like this: auth.Properties.GetTokenValue("access_token")检索 facebook 提供的身份验证令牌,如下所示: auth.Properties.GetTokenValue("access_token")

Then use the token to get the user's profil picture manually like this:然后使用令牌手动获取用户的个人资料图片,如下所示:

    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;
    }

Where PictureData is just a class representing the response from Facebook's graph API with all the info about the picture;其中,PictureData 只是一个类,表示来自 Facebook 图形 API 的响应以及有关图片的所有信息; Height, Width, url etc.高度,宽度,网址等。

There is also a possibility to use custom claim actions to map json user content to claims (claim type to use is up to you).还可以使用自定义声明操作将 json 用户内容映射到声明(要使用的声明类型取决于您)。 So image url will be added to claims collection, no need in OAuthEvents (if you don't need them for other purposes).因此图像 url 将被添加到声明集合中,在 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());
            
        })

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 ASP.Net Core Identity 从登录用户检索 Google 个人资料图片? - How to retrieve Google profile picture from logged in user with ASP.Net Core Identity? 如何使用 ASP.Net Core Identity 3.1 从 controller 中的登录用户获取 Google 和 Facebook 个人资料图片? - How can I get Google and Facebook profile picture from logged in user in a controller with ASP.Net Core Identity 3.1? ASP.NET CORE 5.0 Identity 显示当前登录用户 - ASP.NET CORE 5.0 Identity Display current logged in user ASP.NET Core Identity 中删除登录用户的策略 - Strategies for deleting a logged-in user in ASP.NET Core Identity ASP.NET 核心 MVC 身份 - 如何查看当前登录的用户? - ASP.NET Core MVC Identity - how to get current logged in user in view? ASP.NET 核心 Web API - 如何 ZE0626222614BDEE31951D84C64E5E 使用基于登录用户角色的 DBEE31951D84C64E5E 身份登录用户角色 - ASP.NET Core Web API - How to Select Records based on logged in user role using DB Identity 如何在 ASP.NET Core Identity 中控制器的构造函数中获取登录用户名 - How to get logged-in user name in the constructor of a controller in ASP.NET Core Identity ASP.Net Core 身份和配置文件数据 - ASP.Net Core Identity and Profile Data ASP.NET身份-如何仅允许访问已登录的用户? - ASP.NET Identity - How to allow access to ONLY the logged in User? ASP.NET身份-如何维护登录用户角色? - Asp.net identity - How to maintain logged in user role?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM