我如何在ClaimsIdentity Asp.NetCore中传递对象

时间:2019-03-10 10:33:19

标签: c# asp.net-core asp.net-core-webapi

我如何在Asp.NetCore WebApi中的JWT声明中传递和对象,例如,说我想传递带有ID和名称的Gender对象。

        private IActionResult GenerateJwtToken(string email, ApplicationUser user)
        {

            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(appSettings.Secret);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[] 
                {
                    new Claim(ClaimTypes.Name, user.Id.ToString()),
                    new Claim(ClaimTypes.Email, user.Email.ToString()),
                    new Claim(ClaimTypes.GivenName, user.FirstName.ToString()),
                    new Claim(ClaimTypes.UserData, user.LastName.ToString()),
                    new Claim(ClaimTypes.StreetAddress, user.Address.ToString()),
                    new Claim(ClaimTypes.DateOfBirth, user.DateOfBirth.ToString()),
                    new Claim(ClaimTypes.Rsa, user.FileName.ToString()),
                    new Claim(ClaimTypes.Gender, user.Sex.ToString()),
                    new Claim(ClaimTypes.Country, user.Country.ToString()),
                    new Claim(ClaimTypes.StateOrProvince, user.state.ToString()),
                    new Claim(ClaimTypes.Locality, user.LGA.ToString()),
                    new Claim(ClaimTypes.Hash, user.HairColor.ToString()),
                    new Claim(ClaimTypes.Sid, user.GenoType.Name.ToString()),
                    new Claim(ClaimTypes.Spn, user.BloodGroup.ToString()),
                    new Claim(ClaimTypes.System, user.Religion.ToString()),
                    new Claim(ClaimTypes.NameIdentifier, user.NKName.ToString()),
                    new Claim(ClaimTypes.OtherPhone, user.NKPhoneNumber.ToString()),
                    new Claim(ClaimTypes.SerialNumber, user.NKAddress.ToString()),
                    new Claim(ClaimTypes.GroupSid, user.NKRelationship.ToString()),


                }),

                Expires = DateTime.UtcNow.AddDays(7),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };


            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

            return Ok(new{ token = tokenString });


        }

如果除了Claims之外,还有什么更好的方法可以获取当前登录的用户详细信息,我想知道这一点。预先感谢

[HttpGet("/api/profile")]
public IActionResult Index()
{
    var claimIdentity = this.User.Identity as ClaimsIdentity;
    IEnumerable<Claim> claims = claimIdentity.Claims;

    var model = new IndexViewModel
    {
        Id = claimIdentity.FindFirst(ClaimTypes.Name).Value,
        Email = claimIdentity.FindFirst(ClaimTypes.Email).Value,
        FirstName = claimIdentity.FindFirst(ClaimTypes.GivenName).Value,
        LastName = claimIdentity.FindFirst(ClaimTypes.UserData).Value,
        Address = claimIdentity.FindFirst(ClaimTypes.StreetAddress).Value,
        DateOfBirth = claimIdentity.FindFirst(ClaimTypes.DateOfBirth).Value,
        FileName = claimIdentity.FindFirst(ClaimTypes.Rsa)?.Value,
    };

    return Ok(model);
}

2 个答案:

答案 0 :(得分:0)

由于声明只能存储字符串值,因此您需要将对象表示为字符串。例如,您可以使用Json.net nuget包将对象序列化为json格式/从其反序列化。可能是这样的:

string genderStr = JsonConvert.SerializeObject(gender);
// {
//   "Id": 1,
//   "Name": "Male"
// }
Gender genderObj = JsonConvert.DeserializeObject<Gender>(genderStr);
  

除了Claims之外,还有什么更好的方法来获取当前登录的用户详细信息

我看到您的声明存储在令牌中,可以像您一样从声明中获取它。另一种选择是将用户详细信息存储在某些存储中,例如D B。在这种情况下,您需要从声明中获取用户ID,并从存储中获取所有详细信息。

两个选项都值得考虑。使用第一个选项,您将增加令牌的大小并减少数据库请求的数量。使用第二个选项,您将减小令牌的大小并增加数据库请求的数量。

答案 1 :(得分:0)

我从声明中获取了用户ID,并从这样的存储中获取了详细信息

[HttpGet("/api/profile")]
public async Task < IActionResult > Index() {

   var userId = caller.Claims.Single(c => c.Type == ClaimTypes.Name);
   var user = await userManager.Users.Include(s => s.Sex)
              .SingleOrDefaultAsync(c => c.Id == userId.Value);

    return Ok(user);

}    
相关问题