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

Nor*_*man 3 c# google-api google-oauth asp.net-identity asp.net-core

好的......我目前正在使用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.UseGoogleAuthentication(new GoogleOptions
        {
            AuthenticationScheme = "Google",
            SignInScheme = "Identity.External", // this is the name of the cookie middleware registered by UseIdentity()
            ClientId = Configuration["ExternalLoginProviders:Google:ClientId"],
            ClientSecret = Configuration["ExternalLoginProviders:Google:ClientSecret"]
        });
    }
Run Code Online (Sandbox Code Playgroud)

GoogleOptions附带Microsoft.AspNetCore.Authentication.Google nuget包.

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);
        string email = info.Principal.FindFirstValue(ClaimTypes.Email);
        string firstName = info.Principal.FindFirstValue(ClaimTypes.GivenName);
        string lastName = info.Principal.FindFirstValue(ClaimTypes.Surname);
        //
    }
Run Code Online (Sandbox Code Playgroud)

所以,一切正常,直到这一点.在这里,我被困住了.我读了很多关于accessstokens和声称的文章,名为pictureUrl等.但是校长不包含任何这些.

所以问题是:如何在ExternalLoginCallback函数中检索配置文件图像一次?

emc*_*ing 9

我在ASP.NET Core 2.0上遇到了同样的问题.有一个更好的方法来从OnCreatingTicket你的事件中检索图片startup.cs.在您的情况下,您必须将特定声明"图片"添加到身份.

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddAuthentication()
            .AddCookie()
            .AddGoogle(options =>
            {
                options.ClientId = Configuration["Google.LoginProvider.ClientId"];
                options.ClientSecret = Configuration["Google.LoginProvider.ClientKey"];
                options.Scope.Add("profile");
                options.Events.OnCreatingTicket = (context) =>
                {
                    context.Identity.AddClaim(new Claim("image", context.User.GetValue("image").SelectToken("url").ToString()));

                    return Task.CompletedTask;
                };
            });
    }
Run Code Online (Sandbox Code Playgroud)

然后在您的AccountController中,您可以从外部登录信息方法中选择图像.

var info = await _signInManager.GetExternalLoginInfoAsync();

var picture = info.Principal.FindFirstValue("image");
Run Code Online (Sandbox Code Playgroud)

  • 该答案是较新的,并且是在2019年有效的解决方案。应该以某种方式解决此问题,因为随着技术的变化,对同一主题的答案也应更改。因为花费越来越多的时间才能将正确的答案投票通过。没有专业知识的人就没有时间去尝试每一种以前的解决方案,以找到适用于该软件最新版本的解决方案。 (2认同)

mes*_*sut 9

对于.net core 3.0+,微软使用System.Text.Json来处理google返回的对象,所以我们需要使用这个新API的GetProperty方法来获取图片。

https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/

services.AddAuthentication()
                .AddGoogle(options =>
                {
                    IConfigurationSection googleAuthNSection = Configuration.GetSection("Authentication:Google");

                    options.ClientId = googleAuthNSection["ClientId"];
                    options.ClientSecret = googleAuthNSection["ClientSecret"];
                    options.Scope.Add("profile");
                    options.Events.OnCreatingTicket = (context) =>
                    {                      
                        var picture = context.User.GetProperty("picture").GetString();

                        context.Identity.AddClaim(new Claim("picture", picture));

                        return Task.CompletedTask;
                    };
                });
Run Code Online (Sandbox Code Playgroud)


Nor*_*man 2

我发现无法从声明中获取图片网址。最后我找到了一个使用 nameidentifier 的解决方案,它附带了声明。

string googleApiKey = "{your google api key}";
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
string nameIdentifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
string jsonUrl = $"https://www.googleapis.com/plus/v1/people/{nameIdentifier}?fields=image&key={googleApiKey}";
using (HttpClient httpClient = new HttpClient())
{
    string s = await httpClient.GetStringAsync(jsonUrl);
    dynamic deserializeObject = JsonConvert.DeserializeObject(s);
    string thumbnailUrl = (string)deserializeObject.image.url;
    byte[] thumbnail = await httpClient.GetByteArrayAsync(thumbnailUrl);
}
Run Code Online (Sandbox Code Playgroud)

您只需要一个 Google API 密钥即可。

要创建 API 密钥:

  1. 转到 Google API 控制台。
  2. 从项目下拉列表中选择一个项目,或创建一个新项目。
  3. 启用 Google+ API 服务:

A。在 Google API 列表中,搜索 Google+ API 服务。

b. 从结果列表中选择 Google+ API。

C。按启用 API 按钮。

该过程完成后,Google+ API 将显示在已启用的 API 列表中。要访问,请选择左侧边栏菜单上的 API 和服务,然后选择启用的 API 选项卡。

  1. 在“API 和服务”下的侧栏中,选择凭据。
  2. 在“凭据”选项卡中,选择“新凭据”下拉列表,然后选择“API 密钥”。
  3. 从“创建新密钥”弹出窗口中,为您的项目选择适当的密钥类型:服务器密钥、浏览器密钥、Android 密钥或 iOS 密钥。
  4. 输入密钥名称,按照说明填写任何其他字段,然后选择“创建”。

https://developers.google.com/+/web/api/rest/oauth