Google 认证获取用户头像
Google Authentication get user profile picture
如果用户通过 google 进行身份验证,我需要获取他的个人资料照片。
如果用户通过 facebook 进行身份验证,我将使用以下代码获取他的个人资料图片:
var info = await _signInManager.GetExternalLoginInfoAsync();
var identifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var picture = $"https://graph.facebook.com/{identifier}/picture"; // 3
那么,如果用户通过 google 进行身份验证,我需要在第 3 行中使用哪个代码来获取用户的个人资料图片?
People.get method returns a person object 其中包含
您的用户需要使用配置文件范围进行身份验证。
原始 http 请求
GET https://people.googleapis.com/v1/people/me?personFields=photos HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
回应
{
"resourceName": "people/117200475532672775346",
"etag": "%EgQBAzcuGgQBAgUHIgxHcHNCRHZycjVkZz0=",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "1172004755672775346"
}
},
"url": "https://lh3.googleusercontent.com/a-/AOh14GhroCYJp2P9xeYeYk1npchBPK-zbtTxzNQo0WAHI20=s100"
},
{
"metadata": {
"source": {
"type": "CONTACT",
"id": "3faa96eb0baa4be"
}
},
"url": "https://lh6.googleusercontent.com/-vuhaM1mUvwE/VFOBzFDW-TI/AAAAAAAAAAA/izR9rgfDIyoVoHd7Mq_OJmdbwjhEnfhEQCOQCEAE/s100/photo.jpg"
}
]
}
注意:您也可以从 userinfo 端点获取此信息,但是 Google 不保证他们会在您每次发出请求时发送声明,因此 IMO 最好通过这些人 api.
正在访问用户个人资料图片,完整解决方案。
堆栈:
Asp 网络身份 4 v4 + Asp 网络身份 + Google 人 Api
步骤
1。准备
1.1 我正在使用默认的 HttpClient 生成对 Google API
的 HTTP 请求
1.2 安装 NUGET System.Net.Http.Json 以简化序列化。
1.3 使用 [json to c#] 工具,创建这样的 DTO:
/// <summary>
/// official docs.
/// https://developers.google.com/people/api/rest/v1/people#Person.Photo
/// </summary>
public class PeopleApiPhotos {
public string resourceName { get; set; }
public string etag { get; set; }
public List<Photo> photos { get; set; }
public class Source {
public string type { get; set; }
public string id { get; set; }
}
public class Metadata {
public bool primary { get; set; }
public Source source { get; set; }
}
public class Photo {
public Metadata metadata { get; set; }
public string url { get; set; }
}
}
2。 Identity Server:当用户确认外部信息数据时,发送http get请求,获取头像图片url:
具有 Asp 网络身份的身份服务器 > 登录 > OnPostConfirmationAsync:完整方法
public async Task < IActionResult > OnPostConfirmationAsync(string returnUrl = null) {
returnUrl = returnUrl ? ?Url.Content("~/");
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null) {
ErrorMessage = "Error loading external login information during confirmation.";
return RedirectToPage("./Login", new {
ReturnUrl = returnUrl
});
}
// try to get profile picture
string pictureUri = string.Empty;
if (info.LoginProvider.ToLower() == "google") {
var httpClient = _httpClientFactory.CreateClient();
string peopleApiKey = _configuration["GoogleApiKey:PeopleApiKey"];;
var googleAccountId = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var photosResponse = await httpClient.GetFromJsonAsync < PeopleApiPhotos > (
$ "https://people.googleapis.com/v1/people/{googleAccountId}?personFields=photos&key={peopleApiKey}");
pictureUri = photosResponse ? .photos.FirstOrDefault() ? .url;
}
if (ModelState.IsValid) {
// Cria usuário
var user = new AppUser {
UserName = Input.Email,
Email = Input.Email,
FirstName = Input.FirstName,
LastName = Input.LastName,
ProfilePictureUrl = pictureUri
};
var result = await _userManager.CreateAsync(user);
if (result.Succeeded) {
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded) {
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page("/Account/ConfirmEmail", pageHandler: null, values: new {
area = "Identity",
userId = userId,
code = code
},
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $ "Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
// If account confirmation is required, we need to show the link if we don't have a real email sender
if (_userManager.Options.SignIn.RequireConfirmedAccount) {
return RedirectToPage("./RegisterConfirmation", new {
Email = Input.Email
});
}
await _signInManager.SignInAsync(user, isPersistent: false, info.LoginProvider);
return LocalRedirect(returnUrl);
}
}
foreach(var error in result.Errors) {
ModelState.AddModelError(string.Empty, error.Description);
}
}
ProviderDisplayName = info.ProviderDisplayName;
ReturnUrl = returnUrl;
return Page();
}
2.1 Identity Server with Asp Net Identity > Login > OnPostConfirmationAsync: HIGHLIGHT:
❗️这只是上面完整方法的一小部分。
检查外部提供者是否为 Google,并使用 [NameIdentifier] 和 [Google Api Key] 到达 People Endpoint.
// try to get profile picture
string pictureUri = string.Empty;
if (info.LoginProvider.ToLower() == "google") {
var httpClient = _httpClientFactory.CreateClient();
// ApiKey can get generated in [Google Developers Console](https://console.developers.google.com/apis/credentials).
string peopleApiKey = _configuration["GoogleApiKey:PeopleApiKey"];;
var googleAccountId = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var photosResponse = await httpClient.GetFromJsonAsync < PeopleApiPhotos > (
$ "https://people.googleapis.com/v1/people/{googleAccountId}?personFields=photos&key={peopleApiKey}");
pictureUri = photosResponse ? .photos.FirstOrDefault() ? .url;
}
3。身份服务器 > 配置文件服务实施:
public async Task GetProfileDataAsync(ProfileDataRequestContext context) {
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
var principal = await _claimsFactory.CreateAsync(user);
var claims = principal.Claims.ToList();
claims.Add(new Claim(JwtClaimTypes.GivenName, user.FirstName));
claims.Add(new Claim(JwtClaimTypes.FamilyName, user.LastName));
// Insert a new claim, that gets ProfilePictureUrl persisted in my app user in database.
claims.Add(new Claim(JwtClaimTypes.Picture, user.ProfilePictureUrl));
context.IssuedClaims = claims;
}
4。在 ReactJS 前端访问配置文件用户:
为了在前端获取用户个人资料数据,我正在使用 OidcClient-js
// here i'm using oidc-client.js
// user object is loaded with user full data.
let profilePictureUrl = user.profile.picture;
感谢@DaImTo 的回复。
如果用户通过 google 进行身份验证,我需要获取他的个人资料照片。
如果用户通过 facebook 进行身份验证,我将使用以下代码获取他的个人资料图片:
var info = await _signInManager.GetExternalLoginInfoAsync();
var identifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var picture = $"https://graph.facebook.com/{identifier}/picture"; // 3
那么,如果用户通过 google 进行身份验证,我需要在第 3 行中使用哪个代码来获取用户的个人资料图片?
People.get method returns a person object 其中包含
您的用户需要使用配置文件范围进行身份验证。
原始 http 请求
GET https://people.googleapis.com/v1/people/me?personFields=photos HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
回应
{
"resourceName": "people/117200475532672775346",
"etag": "%EgQBAzcuGgQBAgUHIgxHcHNCRHZycjVkZz0=",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "1172004755672775346"
}
},
"url": "https://lh3.googleusercontent.com/a-/AOh14GhroCYJp2P9xeYeYk1npchBPK-zbtTxzNQo0WAHI20=s100"
},
{
"metadata": {
"source": {
"type": "CONTACT",
"id": "3faa96eb0baa4be"
}
},
"url": "https://lh6.googleusercontent.com/-vuhaM1mUvwE/VFOBzFDW-TI/AAAAAAAAAAA/izR9rgfDIyoVoHd7Mq_OJmdbwjhEnfhEQCOQCEAE/s100/photo.jpg"
}
]
}
注意:您也可以从 userinfo 端点获取此信息,但是 Google 不保证他们会在您每次发出请求时发送声明,因此 IMO 最好通过这些人 api.
正在访问用户个人资料图片,完整解决方案。
堆栈:
Asp 网络身份 4 v4 + Asp 网络身份 + Google 人 Api
步骤
1。准备
1.1 我正在使用默认的 HttpClient 生成对 Google API
的 HTTP 请求
1.2 安装 NUGET System.Net.Http.Json 以简化序列化。
1.3 使用 [json to c#] 工具,创建这样的 DTO:
/// <summary>
/// official docs.
/// https://developers.google.com/people/api/rest/v1/people#Person.Photo
/// </summary>
public class PeopleApiPhotos {
public string resourceName { get; set; }
public string etag { get; set; }
public List<Photo> photos { get; set; }
public class Source {
public string type { get; set; }
public string id { get; set; }
}
public class Metadata {
public bool primary { get; set; }
public Source source { get; set; }
}
public class Photo {
public Metadata metadata { get; set; }
public string url { get; set; }
}
}
2。 Identity Server:当用户确认外部信息数据时,发送http get请求,获取头像图片url:
具有 Asp 网络身份的身份服务器 > 登录 > OnPostConfirmationAsync:完整方法
public async Task < IActionResult > OnPostConfirmationAsync(string returnUrl = null) {
returnUrl = returnUrl ? ?Url.Content("~/");
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null) {
ErrorMessage = "Error loading external login information during confirmation.";
return RedirectToPage("./Login", new {
ReturnUrl = returnUrl
});
}
// try to get profile picture
string pictureUri = string.Empty;
if (info.LoginProvider.ToLower() == "google") {
var httpClient = _httpClientFactory.CreateClient();
string peopleApiKey = _configuration["GoogleApiKey:PeopleApiKey"];;
var googleAccountId = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var photosResponse = await httpClient.GetFromJsonAsync < PeopleApiPhotos > (
$ "https://people.googleapis.com/v1/people/{googleAccountId}?personFields=photos&key={peopleApiKey}");
pictureUri = photosResponse ? .photos.FirstOrDefault() ? .url;
}
if (ModelState.IsValid) {
// Cria usuário
var user = new AppUser {
UserName = Input.Email,
Email = Input.Email,
FirstName = Input.FirstName,
LastName = Input.LastName,
ProfilePictureUrl = pictureUri
};
var result = await _userManager.CreateAsync(user);
if (result.Succeeded) {
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded) {
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page("/Account/ConfirmEmail", pageHandler: null, values: new {
area = "Identity",
userId = userId,
code = code
},
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $ "Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
// If account confirmation is required, we need to show the link if we don't have a real email sender
if (_userManager.Options.SignIn.RequireConfirmedAccount) {
return RedirectToPage("./RegisterConfirmation", new {
Email = Input.Email
});
}
await _signInManager.SignInAsync(user, isPersistent: false, info.LoginProvider);
return LocalRedirect(returnUrl);
}
}
foreach(var error in result.Errors) {
ModelState.AddModelError(string.Empty, error.Description);
}
}
ProviderDisplayName = info.ProviderDisplayName;
ReturnUrl = returnUrl;
return Page();
}
2.1 Identity Server with Asp Net Identity > Login > OnPostConfirmationAsync: HIGHLIGHT:
❗️这只是上面完整方法的一小部分。
检查外部提供者是否为 Google,并使用 [NameIdentifier] 和 [Google Api Key] 到达 People Endpoint.
// try to get profile picture
string pictureUri = string.Empty;
if (info.LoginProvider.ToLower() == "google") {
var httpClient = _httpClientFactory.CreateClient();
// ApiKey can get generated in [Google Developers Console](https://console.developers.google.com/apis/credentials).
string peopleApiKey = _configuration["GoogleApiKey:PeopleApiKey"];;
var googleAccountId = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var photosResponse = await httpClient.GetFromJsonAsync < PeopleApiPhotos > (
$ "https://people.googleapis.com/v1/people/{googleAccountId}?personFields=photos&key={peopleApiKey}");
pictureUri = photosResponse ? .photos.FirstOrDefault() ? .url;
}
3。身份服务器 > 配置文件服务实施:
public async Task GetProfileDataAsync(ProfileDataRequestContext context) {
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
var principal = await _claimsFactory.CreateAsync(user);
var claims = principal.Claims.ToList();
claims.Add(new Claim(JwtClaimTypes.GivenName, user.FirstName));
claims.Add(new Claim(JwtClaimTypes.FamilyName, user.LastName));
// Insert a new claim, that gets ProfilePictureUrl persisted in my app user in database.
claims.Add(new Claim(JwtClaimTypes.Picture, user.ProfilePictureUrl));
context.IssuedClaims = claims;
}
4。在 ReactJS 前端访问配置文件用户:
为了在前端获取用户个人资料数据,我正在使用 OidcClient-js
// here i'm using oidc-client.js
// user object is loaded with user full data.
let profilePictureUrl = user.profile.picture;
感谢@DaImTo 的回复。