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

How to get the current logged in user ID in ASP.NET Core?

我之前在 MVC5 中使用 User.Identity.GetUserId() 完成过此操作,但这似乎在这里不起作用。 User.Identity 没有 GetUserId() 方法。

我正在使用 Microsoft.AspNet.Identity

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

注意:我已经使用 Microsoft.AspNet.Identity 但无法获得扩展方法。所以我想他们两个必须结合使用

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

编辑: 这个答案现在已经过时了。查看 Soren 或 Adrien 的回答,了解在 CORE 1.0

中实现此目的的过时方法

如果您想在 ASP.NET MVC 控制器中使用此功能,请使用

using Microsoft.AspNet.Identity;

User.Identity.GetUserId();

您需要添加 using 声明,因为没有它 GetUserId() 就不会存在。

直到 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);

并通过对象获取用户信息:

var user = await GetCurrentUserAsync();

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

注: 您可以在不使用像 string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email 这样的单行代码的情况下做到这一点,但它不遵守单一责任原则。最好隔离获取用户的方式,因为如果有一天您决定更改用户管理系统,例如使用身份以外的其他解决方案,这会很痛苦,因为您必须检查整个代码。

你可以在你的控制器中获取它:

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

或者像以前一样写一个扩展方法.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;
        }
    }
}

并获取用户 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());
        }
    }
}

如本 post 中某处所述,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);
}

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

尽管 Adrien 的回答是正确的,但您可以在一行中完成所有这些操作。不需要额外的功能或混乱。

有效 我在 ASP.NET Core 1.0

中检查过
var user = await _userManager.GetUserAsync(HttpContext.User);

然后你可以获得变量的其他属性,如user.Email。我希望这对某人有所帮助。

你必须导入 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);

仅适用于 .NET Core 2.0 在 Controller class:

中获取登录用户的用户 ID 需要以下内容
var userId = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

var userId = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);

例如

contact.OwnerID = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

对于ASP.NET核心2.0,Entity Framework核心2.0,AspNetCore.Identity2.0api(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,
        });
    }

回复:

User.Identity.GetUserId();

不存在于 asp.net 身份核心 2.0 中。在这方面,我以不同的方式进行了管理。由于获取用户信息,我创建了一个通用的 class 供整个应用程序使用。

创建公共 class PCommon & 接口 IPCommon 添加引用 using System.Security.Claims

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Common.Web.Helper
{
    public class PCommon: IPCommon
    {
        private readonly IHttpContextAccessor _context;
        public PayraCommon(IHttpContextAccessor context)
        {
            _context = context;
        }
        public int GetUserId()
        {
            return Convert.ToInt16(_context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier));
        }
        public string GetUserName()
        {
            return _context.HttpContext.User.Identity.Name;
        }

    }
    public interface IPCommon
    {
        int GetUserId();
        string GetUserName();        
    }    
}

这里实现common class

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
using Pay.DataManager.Concreate;
using Pay.DataManager.Helper;
using Pay.DataManager.Models;
using Pay.Web.Helper;
using Pay.Web.Models.GeneralViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Pay.Controllers
{

    [Authorize]
    public class BankController : Controller
    {

        private readonly IUnitOfWork _unitOfWork;
        private readonly ILogger _logger;
        private readonly IPCommon _iPCommon;


        public BankController(IUnitOfWork unitOfWork, IPCommon IPCommon, ILogger logger = null)
        {
            _unitOfWork = unitOfWork;
            _iPCommon = IPCommon;
            if (logger != null) { _logger = logger; }
        }


        public ActionResult Create()
        {
            BankViewModel _bank = new BankViewModel();
            CountryLoad(_bank);
            return View();
        }

        [HttpPost, ActionName("Create")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Insert(BankViewModel bankVM)
        {

            if (!ModelState.IsValid)
            {
                CountryLoad(bankVM);
                //TempData["show-message"] = Notification.Show(CommonMessage.RequiredFieldError("bank"), "Warning", type: ToastType.Warning);
                return View(bankVM);
            }


            try
            {
                bankVM.EntryBy = _iPCommon.GetUserId();
                var userName = _iPCommon.GetUserName()();
                //_unitOfWork.BankRepo.Add(ModelAdapter.ModelMap(new Bank(), bankVM));
                //_unitOfWork.Save();
               // TempData["show-message"] = Notification.Show(CommonMessage.SaveMessage(), "Success", type: ToastType.Success);
            }
            catch (Exception ex)
            {
               // TempData["show-message"] = Notification.Show(CommonMessage.SaveErrorMessage("bank"), "Error", type: ToastType.Error);
            }
            return RedirectToAction(nameof(Index));
        }



    }
}

在插入操作中获取用户 ID 和名称

_iPCommon.GetUserId();

谢谢, 马苏德

更新 ASP.NET 核心版本 >= 2.0

在控制器中:

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
    }
}

其他class:

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

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

那么你应该在Startupclass中注册IHttpContextAccessor如下:

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

    // Or you can also register as follows

    services.AddHttpContextAccessor();
}

为了提高可读性,写扩展方法如下:

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);
    }
}

则使用如下:

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;
     }
}

APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value

像这样你会得到索赔

使用可以使用

string userid = User.FindFirst("id").Value;

出于某种原因,NameIdentifier 现在检索用户名 (.net core 2.2)

作为管理员处理其他人的个人资料,您需要获取您正在处理的个人资料的 ID,您可以使用 ViewBag 来捕获该 Id,例如 ViewBag.UserId = userId;而 userId 是您正在使用的方法的字符串参数。

    [HttpGet]

    public async Task<IActionResult> ManageUserRoles(string userId)
    {

          ViewBag.UserId = userId;


        var user = await userManager.FindByIdAsync(userId);

        if (user == null)
        {
            ViewBag.ErrorMessage = $"User with Id = {userId} cannot be found";
            return View("NotFound");
        }

        var model = new List<UserRolesViewModel>();

        foreach (var role in roleManager.Roles)
        {
            var userRolesViewModel = new UserRolesViewModel
            {
                RoleId = role.Id,
                RoleName = role.Name
            };

            if (await userManager.IsInRoleAsync(user, role.Name))
            {
                userRolesViewModel.IsSelected = true;
            }
            else
            {
                userRolesViewModel.IsSelected = false;
            }

            model.Add(userRolesViewModel);
        }
        return View(model);
    }

为了在 razor 视图中获取当前用户 ID,我们可以像这样在视图中注入 UserManager:

@inject Microsoft.AspNetCore.Identity.UserManager<ApplicationUser> _userManager
@{ string userId = _userManager.GetUserId(User); }

希望你觉得有用。

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

private readonly UserManager<IdentityUser> _userManager;

public ExampleController(UserManager<IdentityUser> userManager)
{
    _userManager = userManager;
}

然后:

string userId = _userManager.GetUserId(User);

或异步:

var user = await _userManager.GetUserAsync(User);
var userId = user.Id;

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

确保您已启用 windows 身份验证。如果您启用了匿名身份验证,您可能会得到一个空字符串。

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1&tabs=visual-studio

对于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>();
        }
    }
}

因此您可以像这样使用它:

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();
        }
    }
}

如果您使用的是 JWT 令牌,则此代码有效:

User.FindFirstValue("sub");

我知道已经发布了很多答案,但也许它会对某些人有所帮助,就像对我一样。

我将两种解决方案合二为一,并且能够获得 logged-in 用户及其数据。 我使用的是 DotNet 5。 下面的代码,帮助获得 logged-in 用户。

var user = await _userManager.FindByNameAsync(HttpContext.User.Identity.Name);

我为 _userManager 使用了以下包

using Microsoft.AspNetCore.Identity;

对于 HttpContext,我从 ControllerBase 继承了我的 Controller,对于 ControllerBase Class,我使用了以下包

using Microsoft.AspNetCore.Mvc;