JWT 令牌是如何认证的?

Posted

技术标签:

【中文标题】JWT 令牌是如何认证的?【英文标题】:How is JWT token authenticated? 【发布时间】:2020-04-22 22:15:11 【问题描述】:

这让我很困惑:

因此,当用户登录时,他们会被授予带有签名的 JWT 令牌。这个签名发生在 header+Payload+secret

现在用户有了令牌,他们可以访问受保护的资源。

JWT 如何知道令牌有效?由于在此流程中没有任何内容存储在服务器上,如何与签名进行比较?如果我使用 JWT 调试器,我可以创建一个同样有效的令牌。那么这部分是如何工作的呢?

最后一点让我很困惑。我到处都看到“检查签名”,但没有人详细解释它。

【问题讨论】:

【参考方案1】:

JWT 根据服务器拥有的密钥创建客户端令牌。 JWT 的设计方式是在没有服务器拥有的密钥的情况下无法生成客户端令牌,因此每个密钥都是安全的,密钥始终是安全的。 此外,服务器使用密钥来验证客户端令牌是否有效,并且只有该密钥才能对其进行验证。

【讨论】:

所以每次请求带有令牌时,JWT 都必须进行所有哈希以验证其安全性并确保它与生成的内容匹配?那么服务器确实存储了秘密吗?如果这个秘密泄露出去,那么它就不再安全了,对吧? @qaispak JWT 不会再次对令牌进行哈希处理,他们有一种方法可以在不再次生成令牌的情况下进行验证。如果秘密丢失了,它就不再是安全的了,所以要小心。 那么他们如何验证呢?我发送了一个带有 JWT 令牌的请求。现在我的猜测是服务器会执行算法(payload+header+secret),然后验证是否与签名匹配。对吗? @qaispak 是的,JWT 的最后一段是签名,用于验证令牌是否由发送者签名并且没有以任何方式更改。【参考方案2】:

这里有很多相当笼统的问题,所以我把它分解了一下......

    JWT 如何知道令牌是有效的而不是冒名顶替的令牌?

当您向服务器提交请求时,JWT 会附加到该请求的标头中。此 JWT 先前已由服务器提供(通过身份验证),通常存储在本地存储或 cookie 中,以保持会话。

然后可以使用“jsonwebstoken”包(服务器端)来确定令牌对特定资源的有效性。 JWT 包将解密令牌并比较其签名。这是通过比较密钥来完成的,不应在客户端公开这是一个可能导致令牌无效或有效的变量。另一个可能是令牌到期已超时。例如,如果攻击者窃取了其他人的令牌,他们可能会尝试将该令牌发送到您的服务器并冒充其他人。因此,最好有一个短暂的到期 15m - 1h

    令牌如何对特定路由有效?

嗯,这就是变量无限的地方。 JWT 允许您在令牌内存储信息。例如,如果您有两个不同的用户组,您将在令牌中存储一个值 - 当它最初被签名时 - 说明用户是否属于特定用户组。例如userIsABuyer:假,或 userIsASeller:真。一个好的做法是编写一些中间件来拦截每个进来的请求并检查令牌是否有效。如果有效,您可以附加一个标头,例如“authenticated: true”,为了进一步保护其他内部资源,您可以附加任意数量的标头。例如,“userIsABuyer: false”

https://www.youtube.com/watch?v=25GS0MLT8JU - 这是一段相当不错的视频,深入了解了 JWT。

https://blog.hasura.io/best-practices-of-using-jwt-with-graphql/ - 一个很好的资源,还涵盖了在内存中存储令牌时处理前端应用程序中的持久会话问题

【讨论】:

【参考方案3】:

JWT (JSON Web Token) 是一个自包含访问令牌,这意味着它包含应用程序使用它所需的所有信息(即 JWT 声明)和服务器验证它(即,JWT 标头和 JWT 签名)。所有这些都在一个令牌中。

服务器通过询问这两个问题来验证 JWT。

JWT 是否已过期?JWT Payload 是否被篡改?

第一个:服务器查看 JWT Payload 中的已注册声明,例如“exp”(过期时间)、“iat”(发布时间)声明,以确定 JWT 是否过期(或未过期)。 有关完整注册声明的列表,请参阅 RFC 7519 here。

第二个:服务器查看 JWT Header 中的已注册声明“alg”(算法),以了解在 JWT 生成期间使用了哪种类型的哈希。它使用相同的算法(但使用服务器自己的秘密)来验证 JWT Payload 是否在此过程中被篡改。

希望澄清。

干杯, 内存

【讨论】:

那么服务器每次有请求进来就做第二部分?另外,秘密必须存储在服务器上吗? 是的。 Secret 必须存储在服务器端(在 JWT 生成期间进行原始散列)。但是,第二次检查是可选的。因此,我看到了一些服务器端实现,它们作为可选功能(即 JWT 验证和验证)提供,可以根据您的安全需求启用或禁用。

以上是关于JWT 令牌是如何认证的?的主要内容,如果未能解决你的问题,请参考以下文章

JWT鉴权如何来写一个token令牌认证登录?

使用 jwt 令牌认证识别用户

真正的 Jwt 令牌认证

为啥 JWT 是无状态认证?

Kubernetes集群中微服务之间如何进行JWT认证

如果用于认证的JWT令牌保存在HTTP-Only cookie中,你如何从cookie中读取它,以便我可以在请求头中包含它?