¿Cómo obtener el ID de usuario que ha iniciado sesión actualmente en ASP.NET Core?

Resuelto MRainzo asked hace 9 años • 24 respuestas

He hecho esto antes con MVC5 User.Identity.GetUserId()pero no parece funcionar aquí. El User.Identityno tiene el GetUserId()método.

Estoy usando Microsoft.AspNet.Identity.

MRainzo avatar Jun 08 '15 10:06 MRainzo
Aceptado

Actualización en ASP.NET Core Versión >= 2.0

En el controlador:

public class YourControllerNameController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    
    public YourControllerNameController(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task<IActionResult> YourMethodName()
    {
        var userId =  User.FindFirstValue(ClaimTypes.NameIdentifier) // will give the user's userId
        var userName =  User.FindFirstValue(ClaimTypes.Name) // will give the user's userName
        
        // For ASP.NET Core <= 3.1
        ApplicationUser applicationUser = await _userManager.GetUserAsync(User);
        string userEmail = applicationUser?.Email; // will give the user's Email

       // For ASP.NET Core >= 5.0
       var userEmail =  User.FindFirstValue(ClaimTypes.Email) // will give the user's Email
    }
}

En alguna otra clase:

public class OtherClass
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public OtherClass(IHttpContextAccessor httpContextAccessor)
    {
       _httpContextAccessor = httpContextAccessor;
    }

   public void YourMethodName()
   {
      var userId = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
   }
}

Entonces deberás registrarte IHttpContextAccessoren la Startupclase de la siguiente manera:

public void ConfigureServices(IServiceCollection services)
{
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    // Or you can also register as follows

    services.AddHttpContextAccessor();
}

Para mayor legibilidad, escriba los métodos de extensión de la siguiente manera:

public static class ClaimsPrincipalExtensions
{
    public static T GetLoggedInUserId<T>(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);

        if (typeof(T) == typeof(string))
        {
            return (T)Convert.ChangeType(loggedInUserId, typeof(T));
        }
        else if (typeof(T) == typeof(int) || typeof(T) == typeof(long))
        {
            return loggedInUserId != null ? (T)Convert.ChangeType(loggedInUserId, typeof(T)) : (T)Convert.ChangeType(0, typeof(T));
        }
        else
        {
            throw new Exception("Invalid type provided");
        }
    }

    public static string GetLoggedInUserName(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        return principal.FindFirstValue(ClaimTypes.Name);
    }

    public static string GetLoggedInUserEmail(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        return principal.FindFirstValue(ClaimTypes.Email);
    }
}

Luego use de la siguiente manera:

public class YourControllerNameController : Controller
{
    public IActionResult YourMethodName()
    {
        var userId = User.GetLoggedInUserId<string>(); // Specify the type of your UserId;
        var userName = User.GetLoggedInUserName();
        var userEmail = User.GetLoggedInUserEmail();
    }
}

public class OtherClass
{
     private readonly IHttpContextAccessor _httpContextAccessor;
     public OtherClass(IHttpContextAccessor httpContextAccessor)
     {
         _httpContextAccessor = httpContextAccessor;
     }

     public void YourMethodName()
     {
         var userId = _httpContextAccessor.HttpContext.User.GetLoggedInUserId<string>(); // Specify the type of your UserId;
     }
}
TanvirArjel avatar Sep 02 '2018 08:09 TanvirArjel

Hasta ASP.NET Core 1.0 RC1 :

Es User.GetUserId()del System.Security.Claimsespacio de nombres.

Desde ASP.NET Core 1.0 RC2 :

Ahora tienes que usar. UserManager Puedes crear un método para obtener el usuario actual:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);

Y obtenga información del usuario con el objeto:

var user = await GetCurrentUserAsync();

var userId = user?.Id;
string mail = user?.Email;

Nota: Puede hacerlo sin utilizar un método que escriba líneas individuales como esta string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email, pero no respeta el principio de responsabilidad única. Es mejor aislar la forma en que obtienes el usuario porque si algún día decides cambiar tu sistema de administración de usuarios, como usar otra solución que no sea Identity, será doloroso ya que tendrás que revisar todo tu código.

AdrienTorris avatar Feb 01 '2016 10:02 AdrienTorris

puedes obtenerlo en tu controlador:

using System.Security.Claims;
var userId = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

o escriba un método de extensión como antes .Core v1.0

using System;
using System.Security.Claims;

namespace Shared.Web.MvcExtensions
{
    public static class ClaimsPrincipalExtensions
    {
        public static string GetUserId(this ClaimsPrincipal principal)
        {
            if (principal == null)
                throw new ArgumentNullException(nameof(principal));

            return principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        }
    }
}

y llegar a cualquier lugar donde el usuario ClaimsPrincipal esté disponible :

using Microsoft.AspNetCore.Mvc;
using Shared.Web.MvcExtensions;

namespace Web.Site.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return Content(this.User.GetUserId());
        }
    }
}
Søren avatar Aug 09 '2016 09:08 Søren

Incluí el uso de System.Security.Claims y pude acceder al método de extensión GetUserId()

NB: Ya usaba Microsoft.AspNet.Identity pero no pude obtener el método de extensión. Entonces supongo que ambos deben usarse en conjunto

using Microsoft.AspNet.Identity;
using System.Security.Claims;

EDITAR : Esta respuesta ahora está desactualizada. Mire la respuesta de Soren o Adrien para conocer una forma anticuada de lograr esto en CORE 1.0

MRainzo avatar Jun 08 '2015 05:06 MRainzo