在验证之前使用 JWT 有效负载

Posted

技术标签:

【中文标题】在验证之前使用 JWT 有效负载【英文标题】:use JWT payload before verification 【发布时间】:2018-08-08 13:23:30 【问题描述】:

我正在将 JWT 集成到我的服务中,供移动客户端使用。这个想法是在有效负载中包含用户 ID,并在客户端上使用用户的私钥登录。然后,在服务端,提取用户 id 并使用公钥验证签名。似乎有不少人这样做,基于在验证之前如何提取 JWT 有效负载的问题。但另一方面,通常会声明“在信任 JWT 中的任何信息之前始终验证签名”。

实现这一点的正确方法是什么?我应该将用户 ID 和签名包含在有效负载中,然后使用客户端私钥对其进行签名吗?

【问题讨论】:

【参考方案1】:

使用非对称RSA 私钥/公钥算法,您应该在访问您的有效负载之前验证您的令牌。使用 pub 密钥,您可以验证令牌和解码负载:

    客户端通过 POST 请求向服务发送用户凭据 email: "test@mail.com", password:"secret" 如果凭据匹配,则使用 私钥 签署 JWT 令牌以创建令牌并将 user_id 添加到有效负载。

应持有私钥的服务器或身份验证服务。 不是 您的客户。

    将 JWT 令牌作为响应发送回客户端。 客户端使用公钥来验证和解码您的令牌。 访问您的有效负载声明 (user_id)。

使用对称HMAC 对于单密钥验证(默认算法),您可以在客户端从 base64 解码您的有效负载,而无需在客户端验证您的令牌:

    客户端通过 POST 请求向服务发送用户凭据 email: "test@mail.com", password:"secret" 如果凭据匹配,则使用 JWT secret 签署 JWT 令牌以创建令牌并将 user_id 添加到有效负载。 将 JWT 令牌作为响应发送回客户端。 从 base64 解码您的有效负载并在客户端访问您的声明(user_id)。

【讨论】:

【参考方案2】:

JWT 身份验证通常用于两阶段身份验证逻辑。 首先,您在通过 SSL 的基本身份验证请求中提供您的用户 ID 和密码。 如果它被服务验证,服务会创建一个 JWT 访问令牌并将其发送回客户端。 其次,客户端可以使用此 JWT 进行身份验证(通过 SSL),直到其生命周期结束。 没有必要使用非对称方法为有效负载签名。您可以更快地使用对称密钥,因为您不必在客户端解密它。

您可以找到更多详细信息,例如在this 网站上。

【讨论】:

【参考方案3】:

您的身份验证过程绝对有效。需要从有效负载中提取用户 ID 声明以定位匹配的公钥。只有在验证签名后,您才能“信任”发行者。

在通常的网站身份验证方案中(例如使用用户名/密码登录),令牌由服务器使用唯一的密钥颁发,因此服务器不需要检查有效负载来选择验证密钥。但是当私钥归客户所有时,在移动设备的情况下,每个 jwt 都有不同的签名密钥,因此您的验证过程与通常的不同

【讨论】:

以上是关于在验证之前使用 JWT 有效负载的主要内容,如果未能解决你的问题,请参考以下文章

firebase如何发送一个有效负载包含下划线字符的JWT令牌?

如何验证请求标头、JWT 令牌

我在我的 nestJS 应用程序(使用 authGuard)中使用了 passport-jwt 身份验证策略,如何访问我的控制器中的令牌有效负载?

Laravel Tymon\JWT Auth:在身份验证之前检查未完成的有效令牌?

WSO2 APIM - 在 JWT 有效负载中添加用户角色

JAVA 中的 JWT 身份验证。