ASP.NET Core에서 현재 로그인 한 사용자 ID를 얻는 방법


179

이전에 MVC5를 사용 하여이 작업을 수행 User.Identity.GetUserId()했지만 여기서는 작동하지 않는 것 같습니다. User.Identity나던은이 GetUserId()방법을

나는 사용하고있다 Microsoft.AspNet.Identity


2
이것을 시도 System.Web.HttpContext.Current.User.Identity.Name?
Pravin Deshmukh 2016 년

@PravinDeshmukh에게 감사하지만 ID가 아닌 사용자의 이름을 반환합니다
MRainzo

1
작동해야합니다. asp.net github.com/aspnet/Identity/blob/… 의 샘플을 참조하십시오 . @PravinDeshmukh, vnext에서 System.Web.HttpContext.Current를 사용하지 마십시오.
user960567

1
안녕 @ user960567, 당신은 왜 우리에게 말할 수 있습니까?
Pravin Deshmukh

@PravinDeshmukh는 .NET 코어에서 작동하지 않으며 System.Web 종속성이 없기 때문입니다.
user960567

답변:


148

ASP.NET Core 버전> = 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

        ApplicationUser applicationUser = await _userManager.GetUserAsync(User);
        string userEmail = applicationUser?.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);
   }
}

그럼 당신은 등록해야 IHttpContextAccessor에서 Startup다음과 같이 클래스 :

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

1
그러나 내 경우 사용자가 null을 반환합니까? 내가 뭘 잘못하고 있니?
Sruthi Varghese

사용자로 로그인 했습니까?
TanvirArjel

내 시나리오는 사용자의 사용자 이름이 시스템에 로그인되기를 원하는 것과 같습니다. 우분투 또는 Windows로 보냅니 까? 그리고 Windows에서 이것을 테스트하면서 내 이름으로 로그인했습니다. 하지만 돌아오고 null있습니다.
Sruthi Varghese

그런 다음 코드를 봐야합니다! 여기서 외부 에이전트가 역할을 수행 할 수 있습니다.
TanvirArjel

2
에서 null 결과를 얻은 경우 User.Identity.Name익명 인증이 활성화되어 있기 때문일 수 있습니다. 내가 얻을 수있었습니다 User.Identity.Name확대하여 내 도메인과 사용자 이름을 반환 Properties > launchSettings.json하고, 설정 anonymousAuthenticationfalse, 그리고 windowsAuthenticationtrue.
Andrew Gray

109

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있지만 단일 책임 원칙을 존중하지는 않습니다. 언젠가 Identity 이외의 다른 솔루션을 사용하는 것과 같이 사용자 관리 시스템을 변경하기로 결정하면 전체 코드를 검토해야하기 때문에 고통스러워지기 때문에 사용자를 얻는 방법을 분리하는 것이 좋습니다.


1
System.Security.Claims 네임 스페이스와 Microsoft.AspNet.Identity 어셈블리가 있습니다.
scottheckel

2
나는 asp.net 코어가 의존성 주입을 촉진하기 때문에이 대답이 허용되는 대답보다 낫다고 생각합니다.
Phillip Davis

2
userManager가 사용자에 대한 정보를 검색하기 위해 데이터베이스에 요청하기 때문에 잘못된 방식으로 보입니다. 이 경우 userId는 이미 HttpContext.User에서 사용할 수있었습니다
incognito

@incognito 식별자는 단지 예일 뿐이지 만 사용자 개체에 필요한 모든 정보를 얻을 수 있습니다.
AdrienTorris

2
@Adrien 그러나 문제는 사용자 ID를 얻는 방법이었습니다. 제공된 방법이 가장 효율적이지 않다고 말하고 싶었습니다. 이 경우 의견에서 찾을 수있는 Soren 또는 더 짧은 버전의 답변을 선호합니다.
시크릿

91

컨트롤러에서 얻을 수 있습니다.

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

16
짧은 버전 :var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
CFreitas

1
이 확장 방법은 사용자가 IPrincipal의보기 구성 요소 인 것처럼보기 구성 요소가 아닌 컨트롤러 내부의 사용자에게만 적용됩니다.
adam3039

@AK 당신이 사용할 수있는 Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier))사용자 아이디 정수를 얻을 수
함자 Khanzada

1
@HamzaKhanzada Yep, 작동하지만 너무 길고 못생긴 것처럼 보입니다.
AK

39

System.Security.Claims를 사용하여 포함 시켰으며 GetUserId () 확장 메서드에 액세스 할 수있었습니다.

NB : Microsoft.AspNet.Identity를 이미 사용하고 있었지만 확장 방법을 얻을 수 없었습니다. 둘 다 서로 함께 사용해야한다고 생각합니다

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

편집 :이 답변은 이제 구식입니다. CORE 1.0에서 Soren 또는 Adrien의 답변을 확인하십시오.


17
이것은 비밀 소스 였지만, 당신이 이러한 용도를 추가 한 후 누군가를 위해 보이는 것은 ... var userId = User.GetUserId();
사무라이 켄

4
ClaimsPrincipal (Controller.User)의 .GetUserId () 확장이 => UserManager.GetUserId (User)로 이동했습니다.
Soren

1
System.Security.Claims 사용; var userId = this.User.FindFirst (ClaimTypes.NameIdentifier);
전환

3
이전에 유효한 답변을 확인하고 새로운 "올바른"답변을 정확하게 식별합니다.
pimbrouwers

26

.NET Core 2.0 만 해당 Controller클래스 에서 로그인 한 사용자의 UserID를 가져 오려면 다음이 필요합니다 .

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

또는

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

예 :

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

17

이 게시물의 어딘가에 언급 된 것처럼 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의 서비스에 UserManger를 추가해야합니다. 그렇지 않으면 이것은 이미 그렇습니다.


10

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

이 모든 것 중에서 ASP.NET CORE v 2.0에서 작동하는 유일한 것은 당신입니다. 축하합니다!
Just Fair

이거 야. .NET Core 2.0 이상의 사용자라면 이것이 답입니다
alvinchesaro

1
웹 API + JWT 설정에서 .NET Core 3.1에서 테스트되었습니다. 기본 컨트롤러에서 현재 로그인 한 사용자를 원합니다. 효율적이지 않아 모든 요청에 ​​대해 데이터베이스에서 사용자를 쿼리하는 등입니다. 데이터베이스를 쿼리하지 않고 현재 사용자를 얻는 방법이 있습니까?
Nexus

왜 내 반환 않습니다 "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"에 대한 User.FindFirstValue(ClaimTypes.NameIdentifier);?
puerile

5

Adrien의 대답은 정확하지만 한 줄 로이 작업을 수행 할 수 있습니다. 추가 기능이나 혼란이 필요하지 않습니다.

ASP.NET Core 1.0에서 확인했습니다.

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

그런 다음과 같은 변수의 다른 속성을 얻을 수 있습니다 user.Email. 나는 이것이 누군가를 돕기를 바랍니다.


3
내가 방법을 사용하는 이유는 단일 책임 원칙을 존중하기위한 것입니다. 사용자를 얻는 방법을 분리하지 않으면 언젠가 Identity 이외의 다른 솔루션을 사용하는 것과 같이 사용자 관리 시스템을 수정하기로 결정하면 고통 스러울 것입니다.
AdrienTorris

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

응답:

여기에 이미지 설명을 입력하십시오


내 테스트를 기반으로 this.User.Identity.Name하지만 사용자 이름 인 경향이 있습니다. 내 테스트에서 사용자 이름은 이메일이며 등록에서 사용자 로그인하거나 외부 로그인 (예 : Facebook, Google)에서 로그인합니다. 다음 코드는 userId를 반환합니다. ID 사용자 테이블에 자동 증분 기본 키를 사용하므로 int.Parse입니다. int userId = int.Parse(this.User.FindFirstValue(ClaimTypes.NameIdentifier));
Michael Buen

1
FindByIdAsync사용자 이름을 제공하는 동안 작동하지 않습니다. 로 교체하면 작동합니다 FindByNameAsync.
재스퍼

4

에서 APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value

이 같은 당신은 주장을 얻을 것이다


1

User.Identity.GetUserId ();

asp.net ID 코어 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();

감사합니다, Maksud


1
Startup.cs에 IHttpContextAccessor를 등록해야합니까?
REMESQ

1
REMESQ 없음, 나는 이것을 시작에 주입하지 않았지만 내 응용 프로그램에서 작동
Maksud

1

면도기보기에서 현재 사용자 ID를 얻기 위해 다음과 같이보기에 UserManager를 삽입 할 수 있습니다.

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

도움이 되셨기를 바랍니다.


0

사용은 사용할 수 있습니다

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

어떤 이유로 NameIdentifier는 이제 사용자 이름을 검색합니다 (.net core 2.2)


0

다른 사람의 프로필을 작업하는 관리자로서 작업중인 프로필의 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);
    }

-11

ASP.NET MVC 컨트롤러에서이 기능을 사용하려면

using Microsoft.AspNet.Identity;

User.Identity.GetUserId();

usingGetUserId()이 없으면 문 을 추가해야 합니다.


2
예, "Microsoft.AspNet.Identity 사용"이라는 질문에 포함 시켰습니다. 게시물에 대한 답변으로 해결 방법을 알아 냈습니다.
MRainzo

1
FWIWUser.GetUserId()User.Identity.GetUserId()
lc.

18
문제는 네임 스페이스가 Microsoft.AspNetCore.Identity 인 abou asp.net CORE입니다. 그리고 Microsoft.AspNet.Identity가 아닙니다. 그리고 새로운 네임 스페이스를 사용하면 GetUserId () 확장 메소드가 없습니다. 이 답변이 잘못되었습니다!
파스칼

4
모든 캡에서 쉬움. 그리고 SO에 대해 잘 배우십시오. stackoverflow.blog/2018/04/26/…
smoore4
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.