与只使用1个JWT相比,使用刷新令牌和访问令牌如何能更“安全”?

时间:2020-07-27 19:14:00

标签: security authentication jwt express-jwt

与仅使用1个JWT令牌相比,同时具有刷新和访问令牌的系统如何“安全”?

据我了解,在第一种情况下,服务器将在获得有效刷新令牌的情况下以访问令牌进行响应(如果先前的令牌尚未到期,则不会响应)。在这种情况下,当中间人窃取访问令牌时,他们将只有非常有限的时间来使用它(因为它们通常是短暂的)。

但是:如果中间人窃取了刷新令牌,只要刷新令牌有效,他仍将能够请求新的访问令牌。

因为通常刷新和访问令牌都存储在例如Cookie或localStorage;与仅使用具有更长到期时间的1 JWT相比,此概念有何安全性?

-

我在这里可能会遗漏一些非常简单的东西,但是我无法将其包裹住。除了能够控制“会话”(即刷新令牌的有效性)(因为它存储在内存/数据库中)之外,我看不出有什么好处。

2 个答案:

答案 0 :(得分:1)

您可能很困惑,因为您不需要整个JWT。在您的方案中,一个简单的旧会话ID可能就足够了,并且会更安全。智威汤逊并不是圣杯,而且已被过度使用。

只有以不同方式存储刷新令牌和访问令牌才有意义。将它们放在相同起源的localStorage中几乎没有任何意义,您可以使用寿命更长的访问令牌,就是这样。

但这不是重点。在这种情况下,您甚至不需要JWT。

在典型情况下,通常会有一个身份提供者,如果您愿意的话,可以使用“登录服务器”来发行令牌。这与资源服务器(有时非常混乱地称为客户端)不同,后者实际上是您的后端应用程序。发生的情况是您将未经身份验证的用户发送到身份提供者,例如example-idp.com。他们在example-idp.com上进行身份验证(登录)并建立某种会话,例如,通过在example-idp.com的httpOnly cookie中设置刷新令牌。然后,您的用户将重定向到您的应用程序,该应用程序直接接收访问令牌或可以交换访问令牌的某种代码。无论哪种方式,都将为应用程序源存储访问令牌,即。 example-app.com。它可以是一个cookie,但是通常存储在localStorage中。原因是可能存在多个应用程序(example-app1.com和example-app2.com),javascript客户端将向该应用程序发送相同的令牌,如果将其存储在httpOnly中,它将无法执行此操作cookie(尽管可以安全地抵御XSS)。

这样做的好处是,即使example-app.com(通过XSS)被破坏,并且攻击者也破坏了短暂的访问令牌,但他们仍然无法获得刷新令牌的访问权限,因为这已设置换成其他来源,并且可能作为httpOnly cookie。虽然访问令牌仍然有用,但是XSS需要受害者用户交互(即,用户必须做一些事情来运行攻击者的javascript),因此一旦旧的过期,攻击者可能很难获得新的。

因此,简而言之,如果您不具备所有这些复杂性,而只是具有从相同来源下载的javascript客户端的普通服务器端应用程序,则无需任何令牌或JWT,最安全的选择是正确实现的普通旧会话ID。您可能会争辩说,JWT是无状态的,但是大多数应用程序根本不需要是无状态的(同样,如果您需要令牌吊销,则无论如何它都不能是无状态的)。如果您的应用程序确实需要无状态,并且您将存储刷新令牌与访问令牌的方式完全相同,则可以不使用刷新令牌-但请在设置有效期之前评估风险。

在真正需要访问令牌的地方,通过刷新令牌进行更新等通常是单点登录方案,或者如果您针对不同的实例实现了不同的存储(例如,不同的来源以及httpOnly与javascript可访问性)令牌。

答案 1 :(得分:0)

关于两个令牌比一个更好的原因还有很多话要说。

JWT令牌不仅设计用于与一台服务器通信,还可以与许多服务器通信。这种情况会成倍地增加攻击面,因为与您交谈的每台服务器都具有暴露访问令牌和破坏帐户安全的相同潜力。是否将两个令牌保存在本地存储中不仅是客户端安全性的问题。还需要确保服务器的安全,并且短暂的访问令牌可以减轻例如访问服务器的风险。通过服务器上错误配置的日志处理使您暴露访问令牌。

将访问令牌视为脏令牌,或者将其用于完成任务的令牌。刷新令牌是干净令牌。令牌仅在仅需要与身份验证服务器进行对话时使用。