如何在ASP中获取当前登录的用户ID。网络核心?

我以前用MVC5使用User.Identity.GetUserId()这样做过,但在这里似乎不起作用。 User.Identity没有GetUserId()方法

我正在使用Microsoft.AspNet.Identity

373296 次浏览

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

注意:我已经使用了Microsoft.AspNet.Identity,但无法获得扩展方法。所以我想这两种方法必须相互配合使用

using Microsoft.AspNet.Identity;
using System.Security.Claims;
< p > 编辑: 这个答案现在已经过时了。看看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;

<强> < em >注意: 你可以不使用像string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email这样的方法来写单行,但它不尊重单一责任原则。最好隔离你获取用户的方式,因为如果有一天你决定改变你的用户管理系统,比如使用其他的解决方案而不是Identity,这将是痛苦的,因为你必须审查你的整个代码

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

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

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

如果你启动了一个空项目,你可能需要在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);

Controller类中获取登录用户的UserID需要以下命令:

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

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

如。

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

ASP。NET Core 2.0,实体框架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,
});
}

回应:

enter image description here

User.Identity.GetUserId ();

在asp.net identity core 2.0中不存在。在这方面,我采取了不同的方式。为了获取用户信息,我创建了一个用于整个应用程序的公共类。

创建一个公共类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();
}
}

这里实现了常见类

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






}
}

在插入操作中获取userId和名称

_iPCommon.GetUserId();
< p >谢谢, 马克苏德< / p >

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

在其他班级中:

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


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

然后你应该像下面这样在Startup类中注册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;

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

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

https://learn.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");

我知道已经有很多答案贴出来了,但也许它会像帮助我一样帮助别人。

我将两个解决方案混合成一个,我能够获得登录的用户及其数据。 我用的是dotnet5。 下面的代码,帮助获取登录的用户

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

我对_userManager使用了以下包

using Microsoft.AspNetCore.Identity;

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

using Microsoft.AspNetCore.Mvc;

TLDR:

在controller中添加:

using System.Security.Claims;

然后你可以使用:

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

降低TLDR;

点网6中有一个简单的方法来测试如何获取用户id,并在默认的Blazor WebAssembly核心托管中测试它:

  • 我在天气预报类中添加了一个名为userId的字符串

      public class WeatherForecast
    {
    public DateTime Date { get; set; }
    
    
    public int TemperatureC { get; set; }
    
    
    public string? Summary { get; set; }
    
    
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    public string userId { get; set; } = "nope";
    }
    

    然后在天气预报控制器

  • <李> < p >我添加 using System.Security.Claims; < / p >
  • 在GET方法中,我设置了天气预报。userId到User.FindFirstValue(ClaimTypes.NameIdentifier):

      public IEnumerable<WeatherForecast> Get()
    {
    
    
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
    Date = DateTime.Now.AddDays(index),
    TemperatureC = Random.Shared.Next(-20, 55),
    Summary = Summaries[Random.Shared.Next(Summaries.Length)],
    userId = User.FindFirstValue(ClaimTypes.NameIdentifier)
    })
    .ToArray();
    }
    

最后是FetchData。剃刀我修改表为:

    <table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
<th>User Id</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
<td>@forecast.userId</td>
</tr>
}
</tbody>
</table>

最后我得到: enter image description here < / p >

我希望它能有所帮助,因为在net core 6中,有时很难找到答案