Is a Refresh Token really necessary when using JWT token authentication?

The*_*boy 27 oauth-2.0 jwt http-token-authentication

I am referencing another SO post that discusses using refresh tokens with JWT.

JWT (JSON Web Token) automatic prolongation of expiration

I have an application with a very common architecture where my clients (web and mobile) talk to a REST API which then talks to a service layer and data layer.

在此输入图像描述

I understand JWT token authentication, but I am a little confused at how I should use refresh tokens.

I want my JWT authentication to have the following properties:

  1. JWT Token has expiration of 2 hours.

  2. Token is refreshed every one hour by client.

  3. If user token is not refreshed (user is inactive and app is not open) and expires, they will need to login whenever they want to resume.

I see a lot of people claiming to make this a better experience using the concept of a refresh token, however I don't see the benefit of this. It seems like an added complexity having to manage it.

My questions are the following:

  1. If I WERE to use a refresh token, wouldn't it still be beneficial to have a long term expiration for good practice on that token as well?
  2. If I WERE to use a refresh token, would that token be persisted with the userId and/or JWT token?
  3. When I update my token every 1 hour, how does this work? Will I want to create an endpoint that takes in my JWT token or my refresh token? Will this update the expiration date of my original JWT token, or create a new token?
  4. 鉴于这些细节,是否真的需要刷新令牌?似乎如果用户只是使用JWT令牌来获取新令牌(根据上面的链接),则刷新令牌已过时.

qre*_*0ct 43

让我稍后回答你的问题,然后开始讨论刷新令牌的整个目的.

所以情况是:

用户打开应用程序并提供其登录凭据.现在很可能该应用程序正在与REST后端服务进行交互.REST是无状态的,没有办法授权访问API.因此,到目前为止,在讨论中,没有办法检查授权用户是否实际访问API,或者只是一些随机请求通过.

现在,为了能够解决这个问题,我们需要一种方法来了解请求来自授权用户.所以,我们所做的是引入一种称为访问令牌的东西.因此,一旦用户成功通过身份验证,他就会获得一个访问令牌.这个令牌应该是一个长且高度随机的令牌(以确保它不会被猜到).这就是JWT进入画面的地方.现在,您可能/可能不想在JWT令牌中存储任何特定于用户的详细信息.理想情况下,您只想在JWT中存储非常简单,极其非敏感的细节.JWT(正在使用的库)本身处理JWT哈希的操作以检索其他用户的详细信息(IDOR等).

所以目前我们的授权访问问题已经解决了.

现在我们谈谈一个攻击场景.假设使用上述所有用户,Alice使用该应用程序拥有授权访问令牌,现在她的应用程序可以向所有API发出请求并根据其授权检索数据.

假设SOMEHOW Alice失去了访问令牌或换了另一种方式,攻击者Bob可以访问Alice的访问令牌.现在Bob尽管未经授权,但实际上可以向Alice授权的所有API发出请求.

我们理所当然地想要一些东西.

现在解决这个问题的方法是:

  1. 要么发现有这种事情发生了.
  2. 减少攻击窗口本身.

仅使用访问令牌,很难实现上面的条件1,因为无论是Alice还是Bob,它都是使用的相同授权令牌,因此两个用户的请求是不可区分的.

所以我们尝试实现上面的2,因此我们为访问令牌的有效性添加了一个到期,比如访问令牌对't'(短暂的)时间有效.

它有什么用?好吧,即使Bob拥有访问令牌,他也只能使用它直到它有效.一旦到期,他将不得不再次检索它.现在,你可以说他可以像第一次得到它一样得到它.但话说再说没有100%安全!

上述方法仍存在问题,在某些情况下实际上是不可接受的.当访问令牌到期时,它将要求用户输入他的登录凭证并再次获得授权访问令牌,至少在移动应用的情况下,这是不好的(不可接受的)用户体验.

解决方案:这是刷新令牌进入的位置.它也是一个随机不可预测的令牌,它也首先与访问令牌一起发布给应用程序.此刷新令牌是一个非常长期存在的特殊令牌,它确保一旦访问令牌到期,它就会向服务器请求新的访问令牌,从而无需用户重新输入其登录凭据以检索新的授权访问令牌,一旦现有的已到期.

现在您可能会问,Bob也可以访问刷新令牌,类似于他破坏访问令牌的方式.是.他可以.然而,现在很容易识别出这种情况,这在单独的访问令牌的情况下是不可能的,并采取必要的行动来减少所造成的损害.

怎么样 ?

对于每个经过身份验证的用户(通常是移动应用程序),会向应用程序发出一对一映射刷新令牌和访问令牌对.因此,在任何给定的时间点,对于单个经过身份验证的用户,将只有一个访问令牌对应于刷新令牌.现在假设如果Bob已经破坏了刷新令牌,他将使用它来生成访问令牌(因为访问令牌是唯一被授权通过API访问资源的东西).一旦Bob(攻击者)使用新生成的访问令牌发出请求,因为Alice的(真实用户)访问令牌仍然有效,服务器会将此视为异常,因为对于单个刷新令牌,只能有一个授权一次访问令牌.识别异常,服务器将销毁有问题的刷新令牌,并且与之相关的所有相关访问令牌也将失效.从而防止任何进一步的访问,无论是真正的还是恶意的,都需要资源的任 用户Alice需要再次使用她的凭证进行身份验证并获取有效的刷新和访问令牌.

当然,您仍然可以争辩说Bob可以再次访问刷新和访问令牌,并重复上面的整个故事,可能导致真正的客户Alice的DoS,但是再一次没有100%的安全性.

同样作为一个好习惯,刷新令牌也应该有一个到期,虽然很长.

  • 这是一个很好的答案,给我带来了一些问题。如果 Bob 无法访问 Alice 的电话并且令牌仅通过 HTTPS 发送,他有什么可能的方式窃取访问令牌?您说“对于每个经过身份验证的用户(通常在移动应用程序的情况下),都会向应用程序发出一对一映射的刷新令牌和访问令牌对。” 这是否意味着 Alice 不能在她的手机和台式机上使用相同的令牌?如果是这样,它实际上等同于 Bob 在不同的机器上使用相同的令牌,对吗? (8认同)
  • 如果 Alice 有一段时间没有登录来刷新她的访问令牌怎么办?假设 Alice 在晚上注销,她的访问令牌自然过期,但她的刷新令牌在几天内仍然有效。在这种情况下,鲍勃不能使用爱丽丝的刷新令牌来生成新的访问令牌吗?由于它们不是在数据库中与刷新令牌配对的有效访问令牌,因为它会自然过期。我可能理解最后一次检查是错误的,但这听起来像是查看某人是否获得您的刷新令牌的唯一方法是检查在发出请求时是否只有有效的访问令牌。 (8认同)
  • 很好的答案,但有一些缺陷。“识别出异常情况后,服务器将销毁有问题的刷新令牌,与之相关的访问令牌也将失效”。这不会自动发生。使刷新令牌无效并不意味着访问令牌将被销毁。访问令牌在过期后将失效。“因为对于单个刷新令牌,一次只能有一个授权访问令牌”,人们可以在其过期之前抢先请求更多访问令牌。所以这看起来不正确。 (6认同)
  • 一个登录用户只有一个访问令牌和一个刷新令牌。如果攻击者获得了刷新令牌并创建了另一个访问令牌,那么认证服务器应该检测到用户存在两个不同的访问令牌,并撤销刷新令牌和两个访问令牌,迫使用户再次发送他的凭据,以便获取新的访问令牌和新的刷新令牌。 (3认同)
  • 这是一个很好的答案。一张纸条。Gmail 用户可以拥有多个刷新令牌,因为他们可以拥有多个设备。虽然你是绝对正确的。单个刷新令牌无法在两个设备之间共享。 (3认同)
  • @nomad可以通过多种方式破解访问令牌.1.松开一个人的设备.2.该应用程序有一些漏洞将令牌泄露给设备上的其他应用程序3.底层操作系统版本本身有漏洞,可能是也可能不是零天4.用户自己嗅探自己的流量(HTTPS不会真正帮助)为了获得访问令牌并且在没有到期时使用该令牌,即使在例如说,她已被阻止使用该应用程序等.对于第二个任务,猜测每个新设备,整个身份验证流程将重复发布授权.开放供讨论. (2认同)
  • 此外,在以下情形中:"一旦Bob(攻击者)使用新生成的访问令牌发出请求,因为Alice的(真实用户)访问令牌仍然有效,服务器会将此视为异常,因为对于单个刷新令牌一次只能有一个授权访问令牌",服务器如何知道这是一个异常?因为现有的访问令牌还没有过期吗?如果是这样,那么在到期之前与合法刷新电话有什么不同呢? (2认同)
  • “因为对于单个刷新令牌,一次只能有一个授权访问令牌。识别出异常情况后,服务器将销毁刷新令牌”——这听起来不对。访问令牌无法销毁,只会过期。在那之前,它们都是有效的并且仍然是客户端。 (2认同)
  • 服务器是否必须维护刷新令牌的状态才能发现异常?如果是,那么使用刷新令牌不是无状态实现。这是当前的假设吗? (2认同)

ale*_*emb 10

如果我要使用刷新令牌,那么长期过期对于该令牌的良好实践是否仍然有益?

刷新令牌是长期存在的,访问令牌是短暂的。

如果我要使用刷新令牌,该令牌是否会与 userId 和/或 JWT 令牌一起保留?

它将作为单独的令牌与 JWT 一起保留在客户端上,但不在 JWT 内部。UserID/UID 可以存储在 JWT 令牌本身内。

当我每 1 小时更新一次令牌时,这是如何工作的?我是否想要创建一个接受 JWT 令牌或刷新令牌的端点?这会更新我的原始 JWT 令牌的到期日期,还是创建一个新令牌?

是的,您需要一个单独的服务来颁发和刷新令牌。它不会更新现有 JWT 令牌的到期时间。令牌只是经过 Base64 编码的 JSON 字段值对。因此改变数据就会改变输出。代币还有发行日期,该日期至少会在每次新发行(刷新)时发生变化。因此,每个代币都将是独特且新颖的。旧令牌将自动过期,因此您需要所有访问令牌过期,否则它们将永远徘徊。

这里的另一个答案指出,当您发行新令牌时,旧令牌会被销毁。事实并非如此。代币不能被销毁。事实上,您可以通过不断联系身份验证服务器并使用刷新令牌请求新的新鲜令牌来收获数百个令牌。每个访问令牌将在到期前有效。所以到期是必要的,而且应该是短的。

考虑到这些详细信息,真的需要刷新令牌吗?看来,如果用户只是使用 JWT 令牌来获取新令牌(根据上面的链接),那么刷新令牌就已过时。

JWT 令牌有客户声明。例如,is_manager:true对 JWT 令牌的声明可能允许访问经理级别的功能。现在,如果您决定将用户从经理降级为承包商,这不会立即生效。用户可能仍在使用旧令牌。最后,当过期时,他会访问身份验证服务器来刷新他的令牌。身份验证服务器在没有管理声明的情况下颁发新令牌,用户将无法再访问管理功能。这会创建一个窗口,在此期间用户的声明与服务器不同步。这再次解释了为什么访问令牌应该是短暂的,因此同步可以经常发生。

本质上,您每 15 分钟更新一次授权检查,而不是对每个请求进行检查(这是典型的基于会话的身份验证的工作方式)。如果您想要实时权限而不是每 15 分钟刷新一次,那么JWT 可能不太适合

  • “令牌不能被销毁。”。谢谢。我不敢相信另一个答案得到了这么多票。。。JWT 的全部要点是,您不需要数据库来检查哪些是有效的,哪些是无效的。它应该是无国籍的。。 (5认同)

小智 8

我相信在这种情况下,您可以单独使用访问令牌,使您的客户的生活更轻松,同时保持刷新令牌的安全优势.

这是它的工作方式:

  1. 当您的用户使用凭据(用户名/密码)登录时,您将返回短暂的JWT.您还可以创建存储的db记录:

    • JWT id
    • 用户身份
    • IP地址
    • 用户代理
    • 一个valid标志(默认为TRUE)
    • createdAt
    • updatedAt
  2. 您的客户在每个请求中提交JWT.只要JWT没有过期,它就可以访问资源.如果JWT过期,则在后台刷新它并返回资源和X-JWT新JWT 的附加标头.

  3. 当客户端收到带有X-JWT标头的响应时,它会丢弃旧的JWT并将新的JWT用于将来的请求.

JWT在服务器上的工作原理如何

  1. 使用JWT id查找匹配的db记录.
  2. 检查valid标志是否仍然为真,否则拒绝.
  3. (可选)您可以将请求IP地址和用户代理与存储的IP地址和用户代理进行比较,并决定拒绝某些内容是否可疑.
  4. (可选)您可以检查db记录的createdAt或updatedAt字段,并决定在过多时间后不刷新.
  5. 更新updatedAtdb记录中的字段.
  6. 返回新的JWT(它基本上是过期的JWT的副本,但具有延长的过期时间).

此设计还允许您为用户撤消所有令牌(例如,如果用户丢失手机或更新其密码).

优点:

  • 您的客户端永远不必检查到期时间或刷新令牌请求,它所做的就是检查X-JWT响应中的标头.
  • 您可以根据IP地址,用户代理,最大令牌年龄或这些的组合添加自定义刷新逻辑.
  • 您可以撤消用户的部分或全部令牌.