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