2

新しいアプリケーションでMVCからSPA + APIへアプローチしています。私はその答えを見つけることができないいくつかの質問に直面しています。.NET Core 2 Web APIでJWTを検証した後、ユーザーデータを取得するベストプラクティスは何ですか?

ユーザーストアにIDを使用している.Net Core 2のWeb APIがあります。私は、私のSPAがコントローラへのすべての要求に対してベアラトークンとして送信しているJWTトークンを発行してAPIを保護しています。発行コードは次のとおりです。

private async Task<object> GenerateJwtTokenAsync(ApplicationUser user) 
    { 
     var roles = await _userManager.GetRolesAsync(user); 

     var claims = new List<Claim> 
     { 
      new Claim(JwtRegisteredClaimNames.Sub, user.Email), 
      new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), 
      new Claim(ClaimTypes.NameIdentifier, user.Id) 
     }; 
     claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role))); 

     var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"])); 
     var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 
     var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"])); 

     var token = new JwtSecurityToken(
      _configuration["JwtIssuer"], 
      _configuration["JwtIssuer"], 
      claims, 
      expires: expires, 
      signingCredentials: creds 
     ); 

     return new JwtSecurityTokenHandler().WriteToken(token); 
    } 

私の質問は:コントローラでの要求にサービスを提供するために必要なユーザー情報を取得するためのベストプラクティスは何ですか?

私はJWTトークンを取得していますが、私はユーザー情報を持っていますが、彼らが働いている会社などのユーザーに関する拡張情報はSQLデータベースにあります。

// GET: api/Agreements 
    [HttpGet] 
    public async Task<IEnumerable<Agreement>> GetAgreementsAsync() 
    { 
     var user = await _userManager.GetUserAsync(HttpContext.User); 

     return _context.Agreements.Where(x => x.CompanyId == user.CompanyId); 
    } 

各リクエストでこの情報を取得するには、もう一度DBを調べる必要がありますか?この情報をJWTトークンに入れるべきか、その場合、どのフィールドに "カスタム"情報を入れるべきですか?

答えて

0

ステートレスのままにしておきたい場合は、クライアントが認証を通過してJWTトークンを取得したときに、サーバーがJWTトークンを使用してその要求を即座に承認できることを意味します。つまり、サーバーはデータベースやメモリではなく、どこでもJWTトークンを検索しません。だから、あなたはデータベースや他の場所を調べるオーバーヘッドがありません。

あなたの質問に答えるには、背後にある理由も知っておくべきです。クレーム:"特定のエンティティに関連付けられたクレームのセットはキーと考えることができます。鍵はドアのロックを開くために使用されます。このようにして、クレームはリソースへのアクセスに使用されます。 MSDN

から後でに行かなくてもAPIのリソースのために許可することができるようにするには、DBへの別の要求を行うことはなく、請求項には、最高の認証目的のために使用されていることを心に留めておくので、主にJWTに余分な主張を追加する必要はありませんデータベース。トークンにカスタムクレームを追加して、JWTトークンに暗号化してクライアントに送信することもできます。

認証後、claimIdおよび/またはuserIdをクレームに格納することができます。これは、クレームのコンストラクタが実装される方法であるため、任意の文字列に名前を付けることができます。要求が到着したとき、あなたは請求からcompanyIdを得ることができます。たとえば、単に「companyId」という名前を付けます。その後、

var claims = new List<Claim> 
    { 
     new Claim(JwtRegisteredClaimNames.Sub, user.Email), 
     new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), 
     new Claim(ClaimTypes.NameIdentifier, user.Id), 
     new Claim("companyId", user.companyId.ToString()) // Like this 
    }; 

と会社のid請求

HttpContext.User.FindFirst("companyId").Value 

ためにゲッターを書く。また、複雑なユーザデータのためには、ネットワークでこのデータパスので、このような主張を使用して、あなたドンはならない、ということに注意してください巨大なJWTトークンが欲しい。また、それはあなたがデータを格納し、要求が来たときにそれを得ることができるHttpContext.Sessionを使用することができるため、良い習慣ではありません。これは、セッション記憶域について詳しく書き込む場所ではありません。

関連する問題