【问题标题】:Why IdentityModel JWT library generates the same token when the same Expires is provided?为什么提供相同的 Expires 时,IdentityModel JWT 库会生成相同的令牌?
【发布时间】:2019-06-17 05:40:39
【问题描述】:

我的应用程序中有以下代码用于在 REST API 中生成用于身份验证的 JWT:

    private string GenerateToken(List<Claim> identityFields)
    {
        var key = Convert.FromBase64String(__SECRET);
        var securityKey = new SymmetricSecurityKey(key);
        var descriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(identityFields.ToArray()),
            Expires = DateTime.UtcNow.AddDays(1),
            SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature)
        };

        var handler = new JwtSecurityTokenHandler();
        var token = handler.CreateJwtSecurityToken(descriptor);
        return handler.WriteToken(token);
    }

“identityFields”参数是一个包含来自用户的值的对象(此处不相关)。

我的主要问题是,当我在同一秒内向该方法发送两个请求时(我的意思是,例如,2019-01-23 14:57:59.827 和 2019-01-23 14:57:59.350) ,它为两个会话生成相同的 JWT(当然要记住“identityFields 是相同的”),因为“Expires”属性不关心毫秒。

如何解决这个问题?

我使用的是官方 JWT 库(System.IdentityModel.Tokens.Jwt),不是自定义代码。

谢谢!

【问题讨论】:

  • 为什么会有这个问题?
  • @jps 因为我将该令牌(连同其他一些属性)存储在数据库中的 Session 对象中,当我尝试通过 Token 获取 Session 对象时,它返回多个元素,并且需要是一个单独的
  • 将令牌存储在数据库中似乎有点奇怪;但您可以避免在数据库中存储重复的键。
  • @Jonny 是的,最后我添加了一个验证以防止重复令牌。还有一个问题:为什么将令牌存储在数据库中对您来说很奇怪?我的意思是,我需要令牌,这样我才能获取会话数据(如 ApplicationId、UserId 等),而令牌是 API Rest 的消费者在 Auth 标头中发送给我的唯一东西
  • 为什么不将applicationId, userId 放入 jwt 有效负载本身?这就是jwt的目的,携带信息。

标签: c# rest api asp.net-web-api jwt


【解决方案1】:

我推荐看看https://blogs.msdn.microsoft.com/webdev/2016/10/27/bearer-token-authentication-in-asp-net-core/

根据您的具体用例,您应该能够向您的令牌添加自定义声明,以便您可以直接从令牌中提取所需的信息。

如果您需要对信息保密(因为任何人都可以解码 JWT 令牌),您可以添加一个唯一标识符作为自定义声明,并使用它在您的数据库中查找信息。

【讨论】:

  • 感谢您的回答,但最后我添加了一个验证以防止数据库中出现重复的令牌,因为我需要在某处保留这些额外信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 2017-09-07
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多