Как я могу получить изображение профиля Google и Facebook от зарегистрированного пользователя на контроллере с ASP. Net Core Identity 3.1? - PullRequest
0 голосов
/ 27 апреля 2020

Как получить изображение профиля Google и Facebook от зарегистрированного пользователя в контроллере с ASP.Net Core Identity 3.1?

services.AddAuthentication().AddGoogle(opts =>
{
    opts.ClaimActions.MapJsonKey("urn:google:picture", "picture", "url");
    opts.ClaimActions.MapJsonKey("urn:google:locale", "locale", "string");

    opts.SaveTokens = true;
    opts.Events.OnCreatingTicket = ctx =>
    {
       List<AuthenticationToken> tokens = ctx.Properties.GetTokens().ToList();
       tokens.Add(new AuthenticationToken()
       {
          Name = "TicketCreated",
          Value = DateTime.UtcNow.ToString()
       });
       ctx.Properties.StoreTokens(tokens);
       return Task.CompletedTask;
   };
}

Метод обратного вызова:

public async Task<IActionResult> GoogleResponse(string returnUrl = "/")
    {
        ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return RedirectToAction(nameof(Login));
        }
        var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider,
            info.ProviderKey,
            false);

        if (result.Succeeded)
        {
            var picture = info.Principal.FindFirstValue("urn:google:picture");
            // Should I save picture in User table? (User table has this 'public string PhotoFileName { get; set; }' property)
            var locale = info.Principal.FindFirstValue("urn:google:locale");
            return Redirect(returnUrl);
        }
        else
        {
            User user = new User
            {
                Email = info.Principal.FindFirst(ClaimTypes.Email).Value,
                UserName = info.Principal.FindFirst(ClaimTypes.Email).Value,
                EmailConfirmed = true,
                IpAddress = GetClientIpAddress(),
                FirstName = info.Principal.FindFirstValue(ClaimTypes.GivenName),
                LastName = info.Principal.FindFirstValue(ClaimTypes.Surname)
            };

            IdentityResult identResult = await _userManager.CreateAsync(user);
            if (identResult.Succeeded)
            {
                await _userManager.AddToRoleAsync(user, PolicyTypes.OrdinaryUsers);
                identResult = await _userManager.AddLoginAsync(user, info);
                if (identResult.Succeeded)
                {
                    // If they exist, add claims to the user for:
                    //    Given (first) name
                    //    Locale
                    //    Picture
                    if (info.Principal.HasClaim(c => c.Type == ClaimTypes.GivenName))
                    {
                        await _userManager.AddClaimAsync(user,
                            info.Principal.FindFirst(ClaimTypes.GivenName));
                    }

                    if (info.Principal.HasClaim(c => c.Type == "urn:google:locale"))
                    {
                        await _userManager.AddClaimAsync(user,
                            info.Principal.FindFirst("urn:google:locale"));
                    }

                    if (info.Principal.HasClaim(c => c.Type == "urn:google:picture"))
                    {
                        await _userManager.AddClaimAsync(user,
                            info.Principal.FindFirst("urn:google:picture"));
                    }

                    // Include the access token in the properties
                    var props = new AuthenticationProperties();
                    props.StoreTokens(info.AuthenticationTokens);
                    props.IsPersistent = true;

                    await _signInManager.SignInAsync(user, props);

                    return LocalRedirect(returnUrl);
                }
            }
            return AccessDenied();
        }
    }

UserClaim table

CommentController:

public class CommentController : BaseController
{
    private readonly ICommentRepository _commentRepository;
    private UserManager<User> _userManager;
    public CommentController(ICommentRepository commentRepository, UserManager<User> userManager)
    {
        _commentRepository = commentRepository;
        _userManager = userManager;
    }
}

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Я заменил «urn: google: picture» на «picture» для обобщения, а затем:

Метод ExternalLoginCallback:

public async Task<IActionResult> ExternalLoginCallback(string returnUrl = "/")
{
   ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
   if (info.LoginProvider == "Google")
   {
      await _userManager.AddClaimAsync(user, info.Principal.FindFirst("picture"));
   }
   else if (info.LoginProvider == "Facebook")
   {
      var identifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
      var thumbnailUrl = $"https://graph.facebook.com/{identifier}/picturetype=album";
      await _userManager.AddClaimAsync(user, new Claim("picture",thumbnailUrl));
   }
}

в контроллере:

var claims = await _userManager.GetClaimsAsync(new User { Id = userId });
var claim = claims.FirstOrDefault(x => x.Type == "picture");
var picture = claim.Value;
0 голосов
/ 27 апреля 2020

Кажется, вы сохранили информацию о локали и изображении в таблице AspNetUserClaims. Если пользователь аутентифицирован, в контроллере вы можете напрямую запросить информацию по:

var user =await _userManager.GetUserAsync(User);
var claims = await _userManager.GetClaimsAsync(user);
var locale = claims.Where(x => x.Type == "urn:google:locale").FirstOrDefault().Value;
var picture = claims.Where(x => x.Type == "urn:google:picture").FirstOrDefault().Value;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...