¿Cómo obtener el ID de usuario que ha iniciado sesión actualmente en ASP.NET Core?
He hecho esto antes con MVC5 User.Identity.GetUserId()
pero no parece funcionar aquí. El User.Identity
no tiene el GetUserId()
método.
Estoy usando Microsoft.AspNet.Identity
.
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 IHttpContextAccessor
en la Startup
clase 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;
}
}
Hasta ASP.NET Core 1.0 RC1 :
Es User.GetUserId()
del System.Security.Claims
espacio 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.
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());
}
}
}
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