C# JWT访问令牌与刷新令牌(创建)

C# JWT访问令牌与刷新令牌(创建),c#,asp.net-core,jwt,C#,Asp.net Core,Jwt,我正在创建一个Asp.net核心REST服务。目前正在通过JWT承载令牌进行身份验证 现在,我的代码如下所示: DateTimeOffset dtNow = DateTime.Now; Claim[] claims = new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, strUsername), new Claim(JwtRegisteredC

我正在创建一个Asp.net核心REST服务。目前正在通过JWT承载令牌进行身份验证

现在,我的代码如下所示:

        DateTimeOffset dtNow = DateTime.Now;

        Claim[] claims = new Claim[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, strUsername),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(JwtRegisteredClaimNames.Iat, dtNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
        };

        JwtSecurityToken jwtAccess = new JwtSecurityToken(_options.Issuer, _options.Audience, claims, dtNow.DateTime, dtNow.DateTime.Add(_options.AccessTokenExpiration),
                                                          _options.SigningCredentials);

        var response = new
        {
            access_token = new JwtSecurityTokenHandler().WriteToken(jwtAccess),
            token_type = "Bearer",
            expires_in = (int)_options.AccessTokenExpiration.TotalSeconds,
            refresh_token = ""
        };
问题:

  • 现在,我的访问令牌可用于1小时和刷新 60天的代币。这些价值是否合理
  • 看不多 有关如何创建刷新令牌的文档。。。这是创建的吗 与访问令牌完全相同,只是超时时间不同
  • 我的理解是,我应该将刷新令牌存储在数据库中,如果用户发送刷新令牌请求,我需要验证令牌的签名并确保其在我的数据库中
  • 当用户请求刷新令牌时,我应该返回相同的刷新令牌,无论其是否过期,并让用户担心是否会获得新的刷新令牌
  • 用户一次只能有一个刷新令牌,对吗?如果他们再次授予密码,我只是覆盖刷新令牌,就好像他们得到一个全新的一样
  • 最后一个问题是,我看到人们在做JWT身份验证,这就是我为什么这么做的原因,哈哈,但这和通过HTTPS发送用户名/密码有什么不同?我知道JTW在有效负载中携带state/roles/etc,这样可以节省一个DB调用,但是由于身份验证令牌的寿命很短,他们必须每5分钟获得一个新令牌,所以这一切看起来都像是一次清洗,除非我遗漏了什么
  • 这完全取决于应用程序的需要,但这些听起来确实是合理的数字

  • 它们的创建方式不同。访问令牌通常是包含JWT的令牌。刷新令牌是一个引用令牌,必须保存在提供程序上,并在传入新访问令牌时进行查找

  • 刷新令牌没有要验证的签名。基本上,您将传递诸如客户机Id和secret以及刷新令牌之类的信息,这将允许您获得一个新的访问令牌。比如用户名和密码被保存了很长一段时间,如果需要的话可以被列入黑名单

  • 不,您可以在每次他们请求新的访问令牌时更新刷新令牌,这将为您提供一个“滑动”刷新令牌

  • 他们可以为每个应用程序使用不同的令牌,但每个应用程序在进行新登录时可以覆盖其以前的刷新令牌

  • 是的,用户必须在30分钟内获得一个新的访问令牌,但当您的角色提供程序与您的应用程序不同时,这也会有所帮助。这为API提供了一种查看角色的方法,而无需调用授权服务器。当您将信息存储在令牌中时,请求保存的数量非常大,并且每30分钟只需重新获取一次该信息,而不是为每次API调用或回发向单独的服务器发出额外的HTTP请求


  • 希望其中一些是有帮助的。我说的是一些小经验,但是有很多很好的资源可以从IdentityServer3(现在是4)上的家伙那里或者从他们那里解释这些东西。

    谢谢Tim。请澄清一下#2.我发布的代码,我会创建refresh_令牌吗,与我创建的jwtAccess相同,除了1)60天到期2)将其保存在DB中?你用你的#2答案把我弄糊涂了,因为我看到的每个响应对象,访问令牌和刷新令牌看起来都有点相似?@SledgeHammer抱歉搞糊涂了。有两种类型的令牌:自包含令牌和引用令牌。在自包含令牌中,所有信息(如声明和角色)都将存储在令牌中,并且可以在不调用授权服务的情况下检索。这将是您的访问令牌。引用令牌只是存储在数据库中的标识符。标识符链接到您需要的所有信息,但您必须调用授权服务来获取信息。这将是您的参考标记。2)和3)不正确。由于刷新令牌格式完全是特定于实现的(与访问令牌或授权代码完全相同),因此可以使用JWT、SAML或自定义格式。如果使用JWT或SAML,则将无法达到此目的。JWT包含刷新令牌不应该知道/关心的信息。它应该只是一个存储在授权提供程序上的ID。实际上,不,这不是规范所说的:“刷新令牌是一个字符串,表示资源所有者授予客户端的授权。该字符串对客户端通常是不透明的。”,它的定义与用于访问令牌的定义完全相同:。人们完全可以自由决定如何格式化刷新令牌。它不必是“引用字符串”。