当前位置: 首页 > 知识库问答 >
问题:

JWT认证和刷新令牌的目的

凌昕
2023-03-14

我正在努力围绕JWT身份验证进行思考。我读了很多文章和SO问题,但是其中一些已经过时了,我仍然没有得到满意的答案。

我读过这个SO问题,从JoséF.Romaniello的回答中我明白:

  • 使用刷新令牌,客户端在旧的访问令牌过期之前请求新的访问令牌(这是正常的,预期行为)
  • 在移动应用上,代币永不过期

同样在 auth0 上它说:

您可以请求新的访问令牌,直到刷新令牌在DenyList上。应用程序必须安全地存储刷新令牌,因为它们本质上允许用户永远保持身份验证。

如果刷新令牌可以永远请求新的访问令牌,那么拥有限时访问令牌又有什么意义呢?

然后我读了这个 SO 问题,它引用了上面的 SO 问题。在他的回答中qre0ct说:

……假设Bob泄露了刷新令牌,他将使用它来生成访问令牌(因为访问令牌是唯一被授权通过API访问资源的东西)。一旦Bob(攻击者)请求新生成的访问令牌,因为Alice(真实用户)的访问令牌仍然有效,服务器就会将此视为异常,因为对于单个刷新令牌,一次只能有一个授权的访问令牌。

如果我们假设客户端在任何时候请求新的访问令牌是正常的(每小时,或者每次用户打开Web应用程序,如JoséF. Romaniello所说),服务器将如何区分是Alice还是Bob请求新的访问令牌?为什么这是异常?

另外,很多人说JWT身份验证的优点是服务器不进行数据库调用。但是从上面引用的aust0中,他们提到了DenyList。所以我想每个请求都必须有一个数据库调用来检查令牌是否没有被列入黑名单?没有数据库调用的事情是神话吗?

如果我必须记录列入黑名单的令牌,为什么不直接使用访问令牌并在必要时将其列入黑名单?我无法理解拥有两个令牌的优势,因为如果其中一个被盗,小偷可以永远保持登录状态(尤其是在刷新令牌永远存在的移动应用程序环境中)

提前感谢您的耐心和时间。

共有2个答案

梁研
2023-03-14

这里有几个问题...

回答这个问题最简单的方法是从每个令牌类型的意图开始——实际上有三种类型的令牌都有不同的用途:

  • 访问令牌
  • ID令牌
  • 刷新令牌

访问令牌用作后端API请求的承载令牌,并用于身份验证。它们通常是不包含PII的jwt。如果访问令牌遭到破坏(例如,如果在未加密的请求中使用并被截获),它通常只有10-15分钟的寿命,因此攻击者可以使用它的时间有限。

ID令牌由公共客户端应用程序接收,不应该离开应用程序。它们通常是JWT,可能包含PII,例如用户名、电子邮件、电话,因此应用程序可以从ID令牌中获取此信息,而无需发出后端请求。

刷新令牌用于简化后续身份验证的身份验证过程。而不必使用用户名登录

关于使用JWT身份验证的问题,该服务器不进行数据库调用。这里的意思是JWT身份验证是分布式的。JWT可以通过简单地验证数字签名来验证,而无需发出任何后续的网络请求(除了获取公共签名密钥的初始延迟加载请求)。或者使用不透明令牌,您需要每次向某种数据存储发出网络请求来验证令牌。

WRT 列入黑名单的令牌,一旦颁发了访问令牌,我们通常不会回调 IDP 来验证令牌(它都是分布式身份验证),因此没有将访问令牌列入黑名单的概念。另一方面,可以在 IDP 上阻止刷新令牌,因此当用户/设备尝试刷新令牌交换(以获取新的访问/ID 令牌)时,如果刷新令牌已被撤销,IDP 可以阻止请求。注意:有一些细粒度的 authZ 策略可以在访问令牌在后端过期之前阻止它们,但它可能会变得非常复杂。

司寇阳曦
2023-03-14

在我睡了一觉之后,事情变得明朗了。

我的问题是,我完全是从安全性的角度来观察刷新令牌的。从这个角度来看,我仍然不明白使用刷新令牌是否会带来什么好处。

我已经意识到,刷新令牌的目的是减少DB调用——不是在每个客户端请求时检查访问令牌是否在黑名单中,而是仅在请求新的访问令牌时(因此每个访问令牌生命周期)才进行DB调用,以验证刷新令牌是否在黑名单中或者新的访问令牌是否可以发出。

 类似资料:
  • 我正在构建一个使用JWT进行身份验证的应用程序。我开始做一些研究,但对于诸如刷新令牌和令牌存储之类的主题缺乏共识,我感到惊讶。 据我所知,JWT和OAuth是两个不同的协议,它们遵循不同的规范。 但我的问题是,对于一个没有通过第三方资源服务器如Google、Facebook等认证的应用程序,有一个刷新令牌真的有用吗?为什么不让JWT令牌像刷新令牌一样持续时间长。 另一方面,我可以看到,如本文所述,

  • 这是我的身份验证流程: 用户登录后收到两个令牌(具有过期时间的访问令牌和没有过期时间的刷新令牌) 对于每个用户,刷新令牌存储在数据库中名为refreshTokens的json列中(这是一个数组) 在客户端,访问令牌和刷新令牌都存储在本地存储器上 当需要验证用户时,如果访问令牌过期,将使用刷新令牌创建一个新的访问令牌,并将其发送回用户并保持用户登录 当用户注销时,数据库中存储的刷新令牌(在refre

  • 我正在构建一个移动应用程序,并且正在使用JWT进行身份验证。 最好的方法似乎是将JWT访问令牌与刷新令牌配对,这样我就可以根据需要频繁地使访问令牌过期。 刷新令牌是什么样子的?是随机字符串吗?那串加密了吗?是另一个JWT吗? 刷新令牌将存储在用户模型的数据库中以便访问,对吗?在这种情况下似乎应该加密 在用户登录后,我是否会将刷新令牌发送回,然后让客户端访问单独的路由来检索访问令牌?

  • 我正在做一个项目(没有生产级别,只是为了提高我的技能),我正在使用JWT来处理身份验证。从我所读到的内容来看,仅使用JWT作为访问令牌是非常不安全的,因此我们需要刷新令牌。因此,在登录时,服务器返回一个访问令牌和一个刷新令牌(我将存储在httpOnly cookie中)。访问令牌在短时间内到期,但刷新令牌在到期时用于获取新令牌。 我的问题是,我们何时使用刷新令牌来获取新的访问令牌?是当用户想要获得

  • 我正在使用Tymon提供的包来处理从我的laravel后端到spa前端的Auth,我正在创建AuthController,这几乎是我从文档中获取的,只是稍微调整一下它以满足我的需要。从登录到注销以及令牌过期,一切正常。 问题是,我确实看到该控制器上有一个令牌刷新功能,如果我的猜测是正确的,那就是刷新客户端已经拥有的当前令牌。但是怎么做呢?如何处理前端上的刷新令牌?因为它是相当烦人的,每60分钟(默

  • REST Api目前通过返回JWTS形式的访问和刷新令牌来对用户进行身份验证。本地(用户名/密码)和oauth2.0(目前只有Google)流都可用,因为我为用户提供了这两个不同的身份验证选项。 所有著名的应用程序都没有提示用户进行身份验证,比如说每周或者最糟糕的是每天,但我仍然相信他们的身份验证实践(几乎)是完美无瑕的。 > 是否应该创建一个特定的endpoint(或多个endpoint),以便