ASP.NET Coreで現在ログインしているユーザーIDを取得する方法


179

私は以前にMVC5を使用してこれを実行しましたUser.Identity.GetUserId()が、ここでは機能しないようです。User.Identitydoesntのは、持っているGetUserId()方法を

使ってます Microsoft.AspNet.Identity


2
これを試しますSystem.Web.HttpContext.Current.User.Identity.Nameか?
Pravin Deshmukh

@PravinDeshmukhに感謝しますが、IDではなくユーザーの名前を返します
MRainzo

1
うまくいくはずです。asp.netgithub.com/aspnet/Identity/blob/…にあるサンプルを参照してください。ユーザーがログインしていることを確認してください。@ PravinDeshmukh、決してvnextでSystem.Web.HttpContext.Currentを使用しないでください:)
user960567

1
@ user960567さん、こんにちは。理由を教えてください。
Pravin Deshmukh 2015

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

そして、あなたは登録してくださいIHttpContextAccessorStartup次のようにクラス:

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

私のシナリオでは、システムにログインしているユーザーのユーザー名が必要です。それをUbuntuまたはWindowsにしますか?そして、これをWindowsでテストしているので、自分の名前でログインしています。しかし、それは戻ってきていnullます。
Sruthi Varghese

次に、コードを確認する必要があります!ここで役割を果たす外部エージェントである可能性があります。
TanvirArjel

2
の結果がnullの場合はUser.Identity.Name、匿名認証が有効になっている可能性があります。私は得ることができたUser.Identity.Name拡張することによって、私のドメインとユーザー名を返すためにProperties > launchSettings.json、と設定anonymousAuthenticationするfalse、とwindowsAuthenticationしますtrue
Andrew Grey

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;

注: このように1行を記述するメソッドを使用しなくても実行できます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識別子は単なる例でしたが、ユーザーのオブジェクトで必要なすべての情報を取得できます
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
ビューコンポーネントUserはIPrincipal
adam3039

Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier))整数のUserIdを取得するために使用できる@AK
Hamza Khanzada

1
@HamzaKhanzadaうん、それは機能しますが、とても長く醜く見えます。
AK

39

System.Security.Claimsを使用してインクルードし、GetUserId()拡張メソッドにアクセスできました

注意: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 2017

26

.NET Core 2.0の場合のみ、ControllerクラスにログインしているユーザーのユーザーIDをフェッチするには、以下が必要です。

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で動作する唯一のものです。おめでとう!
ジャストフェア

これだよ。.NET Core 2.0以上の人なら誰でもこれが答えです
alvinchesaro

1
Web API + JWT設定の.NET Core 3.1でテストされています。現在サインインしているユーザーをベースコントローラーで使用する必要があります。これは効率的ではなく、すべての要求に対してデータベースからユーザーにクエリを実行します。データベースにクエリを実行せずに現在のユーザーを取得する方法はありますか?
Nexus

なぜ私は戻る"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"User.FindFirstValue(ClaimTypes.NameIdentifier);ですか?
男子

5

エイドリアンの答えは正しいですが、これはすべて1行で行うことができます。余分な機能や混乱の必要はありません。

ASP.NET Core 1.0で確認しました

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

次に、のような変数の他のプロパティを取得できますuser.Email。これが誰かの役に立つことを願っています。


3
私がメソッドを使用している理由は、単一の責任の原則を尊重するためです。ユーザーを取得する方法を分離しないと、いつかユーザー管理システムを変更することを決定した場合、Identity以外のソリューションを使用するなど、苦痛を伴うことになります。
AdrienTorris 2017

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
Jasper

4

の中に APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value

このような何かはあなたがクレームを取得します


1

User.Identity.GetUserId();

asp.netアイデンティティコア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));
        }



    }
}

挿入アクションでユーザーIDと名前を取得する

_iPCommon.GetUserId();

ありがとう、Maksud


1
Startup.csにIHttpContextAccessorを登録する必要がありますか?
REMESQ 2018年

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

usingこれGetUserId()がないとステートメントが存在しないため、ステートメントを追加する必要があります。


2
ええ、私は「Microsoft.AspNet.Identityの使用」を持っているという質問に含めました。私はそれを解決する方法を考えましたが、投稿の私の回答
MRainzo

1
FWIWそれは(今)でUser.GetUserId()あり、そうではありませんUser.Identity.GetUserId()
lc。

18
問題は、名前空間がMicrosoft.AspNetCore.Identityであるasp.net COREでした。Microsoft.AspNet.Identityではありません。その新しい名前空間を使用すると、GetUserId()拡張メソッドはありません。この答えは間違っています!
Pascal

4
すべて大文字で簡単に。そして、SOで素敵であることについて学びましょう。 stackoverflow.blog/2018/04/26/...
smoore4
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.