asp.net core - route - Forma correcta de obtener la ID de usuario actual en Entity Framework Core
get user id asp net identity core (3)
ASP.NET Core Identity se inyecta a través de DI en startup.cs, por lo que solo tiene que inyectar UserManager a través de un constructor
UserManager<ApplicationUser> userManager
A continuación, puede utilizar lo siguiente en los métodos
_userManager.GetUserId(User);
Esa es la forma en que se usa en la aplicación web de ejemplo cuando crea un nuevo proyecto ASP.NET Core 1 con una cuenta de usuario individual.
Hay un montón de respuestas diferentes flotando por aquí para los diferentes RC''s de ASP.NET Core sobre cómo obtener el ID del usuario que ha iniciado sesión actualmente. Quería hacer la pregunta definitiva aquí. Tenga en cuenta que project.json ahora tiene "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0"
Con RC1, podrías hacer algo como esto:
using Microsoft.AspNet.Identity;
using System.Security.Claims;
User.GetUserId();
Pero con la versión 1 recientemente lanzada de EF Core, Microsoft.AspNet.Identity no es la versión correcta.
Hubo sugerencias para usar UserManager, que parece mucho solo para obtener el usuario que ha iniciado sesión actualmente:
private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
var user = await GetCurrentUserAsync();
var userId = user?.Id;
Otro método que encontré fue:
private readonly UserManager<ApplicationUser> _userManager;
_userManager.GetUserId(User)
Entonces, con ASP.NET Core 1 RTM y EF Core 1 con las siguientes bibliotecas en project.json, ¿cuál es la forma correcta de obtener el ID del usuario que ha iniciado sesión actualmente?
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
La siguiente frase es una versión más concisa de las otras respuestas anteriores.
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
Para explicar un poco más, quería usar la forma más básica de autenticación sin ninguna tabla en la base de datos, así que elegí esta: Usar autenticación de cookies sin identidad de ASP.NET Core de la documentación de Core.
Para que esto funcione, el primer paso es agregar los servicios en Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = new PathString("/Account/Login/");
options.LogoutPath = new PathString("/Account/Logoff/");
options.AccessDeniedPath = new PathString("/Account/AccessDenied/");
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
services.ConfigureApplicationCookie(identityOptionsCookies =>
{
// See https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/
identityOptionsCookies.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
Luego, en el AccountController en la publicación posterior al haber ingresado una identificación de usuario y contraseña válidas, la autenticación más sencilla basada en Reclamaciones es agregar la identificación de inicio de sesión como Reclamación, por ejemplo
var claim = new List {new Claim (ClaimTypes.NameIdentifier, loginViewModel.Guid, ClaimValueTypes.String, emisor),};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal,
new AuthenticationProperties
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(_cookieTimeoutInMinutes),
IsPersistent = true,
AllowRefresh = false
});
Una vez que finaliza el inicio de sesión, puede recuperar el ID de usuario tal como se describe en el forro anterior. Vea la respuesta de Milos Mrdovic más arriba para conocer los pasos más detallados.
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
Consulte la Autorización basada en reclamaciones para obtener más información.
Si está accediendo a esto desde dentro del Controlador, entonces usar UserManager para obtener la ID de usuario es bastante ineficiente, ya que está haciendo un viaje de ida y vuelta a la base de datos. Si está utilizando ClaimsIdentity , puede hacer algo como esto para obtener el ID de usuario:
var claimsIdentity = (ClaimsIdentity)this.User.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
var userId = claim.Value;
Este método simplemente lee el ID de usuario que ya está presente en la cookie, que a su vez se deserializa automáticamente y se almacena en una instancia de ClaimsIdentity .
Yo uso esta clase de ayuda:
public static class UserHelpers
{
public static string GetUserId(this IPrincipal principal)
{
var claimsIdentity = (ClaimsIdentity)principal.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
return claim.Value;
}
}
Así que obtener una identificación de usuario se convierte en:
var userId = this.User.GetUserId();
Si, por algún motivo, la reclamación requerida no está presente en la colección de Reclamaciones , puede agregarla fácilmente al crear la ClaimsIdentity del usuario:
public class ApplicaionUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, this.UserId));
return userIdentity;
}
}