[英]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.