Cách lấy Id người dùng đã đăng nhập hiện tại trong ASP.NET Core


179

Tôi đã làm điều này trước đây với MVC5 bằng cách sử dụng User.Identity.GetUserId()nhưng dường như không hoạt động ở đây. Các User.Identitydoesnt có GetUserId()phương pháp

tôi đang dùng Microsoft.AspNet.Identity


2
thử này System.Web.HttpContext.Current.User.Identity.Name?
Pravin Deshmukh

Cảm ơn bạn @PravinDeshmukh nhưng điều đó trả về tên của người dùng chứ không phải id
MRainzo

1
Nó nên hoạt động. Xem các mẫu trong asp.net github.com/aspnet/Identity/blob/ . Chỉ cần chắc chắn người dùng được đăng nhập @PravinDeshmukh, không bao giờ sử dụng System.Web.HttpContext.Current trong vNext :).
user960567

1
Xin chào @ user960567, bạn có thể vui lòng cho chúng tôi biết lý do không?
Pravin Deshmukh

@PravinDeshmukh vì nó sẽ không hoạt động trên lõi .NET và không có phụ thuộc System.Web.
dùng960567

Câu trả lời:


148

Cập nhật trong phiên bản ASP.NET Core> = 2.0

Trong Bộ điều khiển:

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

        ApplicationUser applicationUser = await _userManager.GetUserAsync(User);
        string userEmail = applicationUser?.Email; // will give the user's Email
    }
}

Trong một số lớp khác:

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

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

Sau đó, bạn nên đăng ký IHttpContextAccessortrong Startuplớp như sau:

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

    // Or you can also register as follows

    services.AddHttpContextAccessor();
}

Để dễ đọc hơn, hãy viết các phương thức mở rộng như sau:

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

Sau đó sử dụng như sau:

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

1
Nhưng người dùng đang trả về null trong trường hợp của tôi? Tôi đang làm sai ở đâu?
Sruthi Varghese

Bạn có chắc chắn rằng bạn đã đăng nhập với một người dùng?
TanvirArjel

Kịch bản của tôi giống như tôi muốn tên người dùng của người dùng đã đăng nhập vào hệ thống của tôi. Hãy để nó là Ubuntu hay Windows? Và khi tôi đang thử nghiệm điều này trong các cửa sổ, tôi đã đăng nhập dưới tên của mình. Nhưng nó đang trở lại null.
Sruthi Varghese

Sau đó phải xem mã của bạn! Có thể là bất kỳ tác nhân bên ngoài đóng một vai trò ở đây.
TanvirArjel

2
Tôi đã thấy rằng nếu bạn có kết quả null từ User.Identity.Nameđó, thì đó có thể là do Xác thực ẩn danh được bật. Tôi đã có thể để có được User.Identity.Nametrở lại tên miền của tôi và tên người dùng bằng cách mở rộng Properties > launchSettings.json, và thiết lập anonymousAuthenticationđể false, và windowsAuthenticationđể true.
Andrew Gray

109

Cho đến khi ASP.NET Core 1.0 RC1 :

Đó là User.GetUserId () từ không gian tên System.Security.Claims .

Kể từ ASP.NET Core 1.0 RC2 :

Bây giờ bạn phải sử dụng UserManager . Bạn có thể tạo một phương thức để có được người dùng hiện tại:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);

Và lấy thông tin người dùng với đối tượng:

var user = await GetCurrentUserAsync();

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

Lưu ý: Bạn có thể làm điều đó mà không cần sử dụng phương pháp viết các dòng đơn như thế này string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email, nhưng nó không tôn trọng nguyên tắc trách nhiệm duy nhất. Tốt hơn hết là cô lập cách bạn có được người dùng vì nếu một ngày nào đó bạn quyết định thay đổi hệ thống quản lý người dùng của mình, như sử dụng một giải pháp khác ngoài Danh tính, sẽ rất đau đớn vì bạn phải xem lại toàn bộ mã của mình.


1
Tôi có không gian tên System.Security.Claims và Microsoft.AspNet.Identity.
scottheckel

2
Tôi nghĩ rằng câu trả lời này tốt hơn câu trả lời được chấp nhận, đặc biệt là vì lõi asp.net đang thúc đẩy tiêm phụ thuộc.
Phillip Davis

2
Có vẻ sai cách vì userManager sẽ yêu cầu cơ sở dữ liệu để lấy thông tin về người dùng. Và trong trường hợp này, userId đã có sẵn trong HttpContext.User
ẩn danh

@incognito Mã định danh chỉ là một ví dụ nhưng bạn có thể nhận được tất cả thông tin bạn cần với đối tượng người dùng
AdrienTorris

2
@Adrien nhưng câu hỏi là làm thế nào để có Id người dùng. Chỉ muốn nói rằng cách cung cấp không phải là hiệu quả nhất. Trong trường hợp này, tôi muốn trả lời bởi Soren hoặc phiên bản ngắn hơn có thể tìm thấy trong các bình luận.
ẩn danh

91

bạn có thể lấy nó trong bộ điều khiển của bạn:

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

hoặc viết một phương thức mở rộng như trước .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;
        }
    }
}

và nhận bất cứ nơi nào người dùng ClaimsPrincipal có sẵn :

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

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

16
Phiên bản ngắn hơn:var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
CFreitas

1
Lưu ý rằng phương thức tiện ích mở rộng này chỉ hoạt động cho Người dùng bên trong bộ điều khiển, không xem các thành phần, vì thành phần xem Người dùng là của IPrincipal
adam3039

@AK bạn có thể sử dụng Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier))để lấy số nguyên UserId
Hamza Khanzada

1
@ HamzaKhanzada Yep, nó hoạt động, nhưng trông rất dài và xấu.
AK

39

Tôi đã sử dụng System.Security.Claims và tôi có thể truy cập phương thức tiện ích mở rộng GetUserId ()

NB: Tôi đã sử dụng Microsoft.AspNet.Identity nhưng không thể có được phương thức mở rộng. Vì vậy, tôi đoán cả hai phải được sử dụng kết hợp với nhau

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

EDIT : Câu trả lời này hiện đã lỗi thời. Hãy xem câu trả lời của Soren hoặc Adrien để biết cách đạt được điều này trong CORE 1.0


17
Đây là nước sốt bí mật, nhưng đối với bất kỳ ai tìm kiếm sau khi bạn thêm những cách sử dụng này thì đó là ... var userId = User.GetUserId();
Samurai Ken

4
Phần mở rộng .GetUserId () từ ClaimsPrincipal (Controller.User) đã được chuyển đến => UserManager.GetUserId (Người dùng);
Soren

1
sử dụng System.Security.Claims; var userId = this.User.FindFirst (ClaimTypes.NameIdentifier);
Chuyển

3
Đồng ý với câu trả lời hợp lệ trước đó và xác định chính xác câu trả lời "đúng" mới.
pimbrouwers

26

Chỉ dành cho .NET Core 2.0 Yêu cầu sau đây để tìm nạp ID người dùng của người dùng đã đăng nhập trong một Controllerlớp:

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

hoặc là

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

ví dụ

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

17

Như đã nêu ở đâu đó trong bài đăng này, phương thức GetUserId () đã được chuyển sang 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);
}

Nếu bạn đã bắt đầu một dự án trống, bạn có thể cần thêm UserManger vào các dịch vụ của mình trong startup.cs. Nếu không thì đây đã là trường hợp.


10

bạn phải nhập 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);

từ tất cả các anwsers này, cái của bạn là cái duy nhất hoạt động với ASP.NET CORE v 2.0. Xin chúc mừng!
Chỉ cần hội chợ

đây là nó. Bất kỳ ai từ .NET Core 2.0 trở lên, đây là câu trả lời của bạn
alvinchesaro

1
Đã thử nghiệm trên .NET Core 3.1 trong cài đặt API Web + JWT. Tôi muốn người dùng hiện đang đăng nhập trong bộ điều khiển cơ sở, điều này không hiệu quả, truy vấn người dùng từ cơ sở dữ liệu cho mọi yêu cầu, v.v ... Có cách nào để có được người dùng hiện tại mà không cần truy vấn cơ sở dữ liệu không?
Nexus

tại sao tôi trở lại "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"cho User.FindFirstValue(ClaimTypes.NameIdentifier);?
puerile

5

Mặc dù câu trả lời của Adrien là chính xác, bạn có thể làm tất cả trong một dòng. Không cần thêm chức năng hoặc lộn xộn.

Nó hoạt động Tôi đã kiểm tra nó trong ASP.NET Core 1.0

var user = await _userManager.GetUserAsync(HttpContext.User);

sau đó bạn có thể nhận được các thuộc tính khác của biến như thế nào user.Email. Tôi hi vọng điêu nay se giup được ai đo.


3
Lý do tại sao tôi sử dụng một phương pháp là để tôn trọng nguyên tắc phản hồi duy nhất. Nếu bạn không cô lập cách bạn có được người dùng, sẽ rất đau đớn nếu một ngày nào đó bạn quyết định sửa đổi hệ thống quản lý người dùng của mình, như sử dụng một giải pháp khác ngoài Danh tính.
AdrienTorris

5

Đối với ASP.NET Core 2.0, Entity Framework Core 2.0, AspNetCore.Identity 2.0 api ( https://github.com/kkagill/ContosoUniversity-Backend ):

Đã Idđược đổi thànhUser.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,
        });
    }

Phản ứng:

nhập mô tả hình ảnh ở đây


Dựa trên thử nghiệm của tôi, this.User.Identity.Namecó xu hướng là tên người dùng mặc dù. Trong thử nghiệm của tôi, tên người dùng là một email, là người dùng đăng nhập từ đăng ký hoặc đăng nhập từ đăng nhập bên ngoài (ví dụ: Facebook, Google). Mã sau trả về userId. Tôi sử dụng khóa chính tăng tự động cho bảng người dùng nhận dạng của mình, do đó int.Pude. int userId = int.Parse(this.User.FindFirstValue(ClaimTypes.NameIdentifier));
Michael Buen

1
FindByIdAsynckhông hoạt động như bạn đang cung cấp một tên người dùng. Nó hoạt động khi bạn thay thế nó bằng FindByNameAsync.
Jasper

4

bên trong APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value

Một cái gì đó như thế này bạn sẽ nhận được yêu cầu


1

Người dùng.Identity.GetUserId ();

không tồn tại trong lõi nhận dạng asp.net 2.0. về vấn đề này, tôi đã quản lý theo cách khác nhau. tôi đã tạo một lớp chung để sử dụng toàn bộ ứng dụng, vì nhận được thông tin người dùng.

tạo một lớp chung PCommon & giao diện IPCommon thêm tài liệu tham khảousing 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();        
    }    
}

Ở đây việc thực hiện lớp học chung

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



    }
}

nhận userId và tên trong hành động chèn

_iPCommon.GetUserId();

Cảm ơn, Maksud


1
Bạn có phải đăng ký IHttpContextAccessor trong Startup.cs không?
REMESQ

1
Không có REMESQ, tôi đã không đưa nó vào khởi động, nhưng hoạt động trong ứng dụng của mình
Maksud

1

Để nhận id người dùng hiện tại trong chế độ xem dao cạo, chúng tôi có thể đưa UserManager vào chế độ xem như sau:

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

Tôi hy vọng bạn thấy nó hữu dụng.


0

sử dụng có thể sử dụng

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

vì một số lý do, NameIdentifier hiện lấy lại tên người dùng (.net core 2.2)


0

Là quản trị viên làm việc trên hồ sơ của người khác và bạn cần lấy Id của hồ sơ bạn đang làm việc, bạn có thể sử dụng ViewBag để chụp Id, ví dụ ViewBag.UserId = userId; trong khi userId là chuỗi Tham số của phương thức bạn đang làm việc.

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

-11

Nếu bạn muốn điều này trong ASP.NET MVC Controller, hãy sử dụng

using Microsoft.AspNet.Identity;

User.Identity.GetUserId();

Bạn cần thêm usingcâu lệnh vì GetUserId()sẽ không ở đó mà không có nó.


2
Phải, tôi đã bao gồm trong câu hỏi rằng tôi có "sử dụng Microsoft.AspNet.Identity". Tôi đã tìm ra cách giải quyết nó mặc dù với câu trả lời của tôi trên bài đăng
MRainzo

1
FWIW nó (bây giờ) User.GetUserId()và khôngUser.Identity.GetUserId()
lc.

18
Câu hỏi đã và là abou asp.net CORE có không gian tên Microsoft.AspNetCore.Identity; và KHÔNG Microsoft.AspNet.Identity; Và sử dụng không gian tên mới đó, không có phương thức mở rộng NO GetUserId (). CÂU TRẢ LỜI NÀY SAU!
Pascal

4
Dễ dàng trên TẤT CẢ CAPS. Và tìm hiểu về việc tốt đẹp trên SO. stackoverflow.blog/2018/04/26/ trên
smoore4
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.