我有一个可行的解决方案,但我想知道这是否是正确的方法。这是我到目前为止所得到的。
我正在使用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);
}
}
//...
}
所以这段代码工作得很好但是,如前所述,这是正确的方法(技术上,而不是基于意见的)吗?
答案 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());
})