如何在ASP.NET Core中获取当前登录的用户标识

MRa*_*nzo 139 asp.net asp.net-identity asp.net-core-mvc asp.net-core-1.0

在使用MVC5之前我已经完成了这个,User.Identity.GetUserId()但这似乎不适用于此.本User.Identity可是没有的GetUserId()方法

我在用 Microsoft.AspNet.Identity

Adr*_*ris 102

直到ASP.NET Core 1.0 RC1:

它是System.Security.Claims命名空间中的User.GetUserId().

自ASP.NET Core 1.0 RC2:

您现在必须使用UserManager.您可以创建一个方法来获取当前用户:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
Run Code Online (Sandbox Code Playgroud)

并获取对象的用户信息:

var user = await GetCurrentUserAsync();

var userId = user?.Id;
string mail = user?.Email;
Run Code Online (Sandbox Code Playgroud)

注意: 您可以在不使用像这样编写单行的方法的情况下执行此操作string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email,但它不遵守单一责任原则.最好隔离你获得用户的方式,因为如果有一天你决定改变你的用户管理系统,比如使用另一个解决方案而不是身份,那么由于你必须检查你的整个代码,它会变得很痛苦.

  • 我认为这个答案比公认的答案要好,尤其是因为 asp.net core 正在促进依赖注入。 (2认同)
  • 似乎是错误的方式,因为userManager将向数据库发出请求以检索有关用户的信息。在这种情况下,userId在HttpContext.User中已经可用 (2认同)
  • @Adrien 但问题是如何获取用户 ID。只是想说提供的方式不是最有效的。对于这种情况,我更喜欢 Soren 的回答或可以在评论中找到的较短版本。 (2认同)

Tan*_*jel 100

ASP.NET Core 2.1和2.2中的更新:

在控制器中:

public class YourControllerNameController : Controller
{
    public 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
        var userEmail =  User.FindFirstValue(ClaimTypes.Email) // will give the user's Email
    }
}
Run Code Online (Sandbox Code Playgroud)

在其他一些课程中:

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

   public void YourMethodName()
   {
      var userId = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
   }
}
Run Code Online (Sandbox Code Playgroud)

然后你应该IHttpContextAccessorStartup课堂上注册如下:

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

    // Or you can also register as follows

    services.AddHttpContextAccessor();
}
Run Code Online (Sandbox Code Playgroud)

  • 但是用户在我的情况下返回 null ?我哪里做错了? (2认同)
  • 我发现如果您从“User.Identity.Name”得到空结果,可能是因为启用了匿名身份验证。通过展开“Properties &gt; launchSettings.json”,并将“anonymousAuthentication”设置为“false”,将“windowsAuthentication”设置为“true”,我能够让“User.Identity.Name”返回我的域和用户名。 (2认同)

Sor*_*ren 77

你可以在你的控制器中得到它:

using System.Security.Claims;
var userId = this.User.FindFirstValue(ClaimTypes.NameIdentifier);
Run Code Online (Sandbox Code Playgroud)

或者像以前一样写一个扩展方法.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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并获得用户ClaimsPrincipal可用的任何地方:

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

namespace Web.Site.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return Content(this.User.GetUserId());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 更短的版本:`var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);` (14认同)

MRa*_*nzo 38

我包括使用System.Security.Claims,我可以访问GetUserId()扩展方法

注意:我已经使用了Microsoft.AspNet.Identity,但无法获得扩展方法.所以我猜两者都必须相互结合使用

using Microsoft.AspNet.Identity;
using System.Security.Claims;
Run Code Online (Sandbox Code Playgroud)

编辑:这个答案现在已经过时了.看看Soren's或Adrien的回答,找出在CORE 1.0中实现这一目标的过时方式

  • 这是秘诀,但对于任何人在添加这些使用后看起来都是......`var userId = User.GetUserId();` (17认同)
  • 来自ClaimsPrincipal(Controller.User)的.GetUserId()扩展已移至=> UserManager.GetUserId(User); (4认同)
  • 竖起以前有效的答案,并正确识别新的"正确"答案. (3认同)

小智 24

仅适用于.NET Core 2.0以下是获取类中已登录用户的UserID所必需的Controller:

var userId = this.User.FindFirstValue(ClaimTypes.NameIdentifier);
Run Code Online (Sandbox Code Playgroud)

要么

var userId = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
Run Code Online (Sandbox Code Playgroud)

例如

contact.OwnerID = this.User.FindFirstValue(ClaimTypes.NameIdentifier);
Run Code Online (Sandbox Code Playgroud)


小智 15

正如本文中的某处所述,GetUserId()方法已移至UserManager.

private readonly UserManager<ApplicationUser> _userManager;

public YourController(UserManager<ApplicationUser> userManager)
{
    _userManager = userManager;
}

public IActionResult MyAction()
{
    var userId = _userManager.GetUserId(HttpContext.User);

    var model = GetSomeModelByUserId(userId);

    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

如果您启动了一个空项目,则可能需要在startup.cs中将UserManger添加到您的服务中.否则这应该是这种情况.


小智 14

你必须导入 Microsoft.AspNetCore.Identity & System.Security.Claims

// to get current user ID
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

// to get current user info
var user = await _userManager.FindByIdAsync(userId);
Run Code Online (Sandbox Code Playgroud)


Sum*_*one 7

在 .net core 3.1(以及其他更新的版本)中,您可以使用:

private readonly UserManager<IdentityUser> _userManager;

public ExampleController(UserManager<IdentityUser> userManager)
{
    _userManager = userManager;
}
Run Code Online (Sandbox Code Playgroud)

然后:

string userId = _userManager.GetUserId(User);
Run Code Online (Sandbox Code Playgroud)

或异步:

var user = await _userManager.GetUserAsync(User);
var userId = user.Id;
Run Code Online (Sandbox Code Playgroud)

在这一点上,我试图弄清楚为什么你会使用一个而不是另一个。我知道异步的一般好处,但看到这两个经常使用。如果有人知道,请发表一些评论。


小智 6

在里面 APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value
Run Code Online (Sandbox Code Playgroud)

像这样的事情你会得到索赔


Dav*_*ang 6

对于ASP.NET 5.0,我有一个扩展方法如下:

using System;
using System.ComponentModel;
using System.Security.Claims;

namespace YOUR_PROJECT.Presentation.WebUI.Extensions
{
    public static class ClaimsPrincipalExtensions
    {
        public static TId GetId<TId>(this ClaimsPrincipal principal)
        {
            if (principal == null || principal.Identity == null || 
                !principal.Identity.IsAuthenticated)
            {
                throw new ArgumentNullException(nameof(principal));
            }

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

            if (typeof(TId) == typeof(string) || 
                typeof(TId) == typeof(int) || 
                typeof(TId) == typeof(long) || 
                typeof(TId) == typeof(Guid))
            {
                var converter = TypeDescriptor.GetConverter(typeof(TId));

                return (TId)converter.ConvertFromInvariantString(loggedInUserId);
            }

            throw new InvalidOperationException("The user id type is invalid.");
        }

        public static Guid GetId(this ClaimsPrincipal principal)
        {
            return principal.GetId<Guid>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你可以像这样使用它:

using Microsoft.AspNetCore.Mvc;
using YOUR_PROJECT.Presentation.WebUI.Extensions;

namespace YOUR_PROJECT.Presentation.WebUI.Controllers
{
    public class YourController :Controller
    {
        public IActionResult YourMethod()
        {
            // If it's Guid
            var userId = User.GetId();

            // Or
            // var userId = User.GetId<int>();

            return View();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ahm*_*mad 5

虽然Adrien的答案是正确的,但你可以单行完成.不需要额外的功能或混乱.

它工作我在ASP.NET Core 1.0中检查它

var user = await _userManager.GetUserAsync(HttpContext.User);
Run Code Online (Sandbox Code Playgroud)

然后你可以获得变量的其他属性user.Email.我希望这可以帮助别人.

  • 我之所以使用一种方法,是为了尊重单一职责原则。如果你不隔离你获取用户的方式,如果有一天你决定修改你的用户管理系统,比如使用除 Identity 之外的其他解决方案,那将是痛苦的。 (3认同)

小智 5

对于ASP.NET Core 2.0,Entity Framework Core 2.0,AspNetCore.Identity 2.0 api(https://github.com/kkagill/ContosoUniversity-Backend):

Id改为User.Identity.Name

    [Authorize, HttpGet("Profile")]
    public async Task<IActionResult> GetProfile()
    {
        var user = await _userManager.FindByIdAsync(User.Identity.Name);

        return Json(new
        {
            IsAuthenticated = User.Identity.IsAuthenticated,
            Id = User.Identity.Name,
            Name = $"{user.FirstName} {user.LastName}",
            Type = User.Identity.AuthenticationType,
        });
    }
Run Code Online (Sandbox Code Playgroud)

响应:

在此输入图像描述