【发布时间】:2015-08-11 22:42:02
【问题描述】:
(源自this thread,因为这确实是其自身的问题,而不是特定于 NodeJS 等)
我正在实现一个带有身份验证的 REST API 服务器,并且我已经成功实现了 JWT 令牌处理,以便用户可以使用用户名/密码通过 /login 端点登录,在该端点上从服务器密钥生成 JWT 令牌和返回给客户。然后在每个经过身份验证的 API 请求中将令牌从客户端传递到服务器,然后使用服务器机密来验证令牌。
但是,我正在尝试了解有关应如何以及在何种程度上验证令牌的最佳实践,以构建真正安全的系统。 “验证”令牌究竟应该涉及什么?可以使用服务器秘密验证签名是否足够,或者我是否还应该针对存储在服务器中的某些数据交叉检查令牌和/或令牌有效负载?
基于令牌的身份验证系统仅与在每个请求中传递用户名/密码一样安全,前提是获取令牌与获取用户密码相同或更难。但是,在我看到的示例中,生成令牌所需的唯一信息是用户名和服务器端密码。这是否意味着假设恶意用户一分钟了解服务器机密,他现在可以代表 any 用户生成令牌,从而不仅可以访问一个给定的用户是否获得了密码,但实际上是所有用户帐户?
这让我想到了问题:
1) JWT 令牌验证是否应该仅限于验证令牌本身的签名,仅依靠服务器机密的完整性,还是伴随单独的验证机制?
在某些情况下,我看到了令牌和服务器会话的组合使用,在通过 /login 端点成功登录后,会建立会话。 API 请求验证令牌,并将令牌中的解码数据与会话中存储的一些数据进行比较。然而,使用会话意味着使用 cookie,并且在某种意义上它违背了使用基于令牌的方法的目的。这也可能给某些客户带来问题。
1234563通过 /login 端点生成的将被接受。这是合理的还是只是多余/过度杀伤?
2) 如果 JWT 签名验证是验证令牌的唯一手段,这意味着服务器机密的完整性是断点,那么服务器机密应该如何管理?从环境变量中读取并在每个部署的堆栈中创建(随机?)一次?定期更新或轮换(如果是这样,如何处理在轮换之前创建但需要在轮换后验证的现有有效令牌,如果服务器在任何给定时间保持当前和以前的秘密就足够了) ?还有什么?
当谈到服务器机密被泄露的风险时,也许我只是过于偏执,这当然是一个更普遍的问题,需要在所有加密情况下解决......
【问题讨论】:
-
有很多很好的问题。回复:问题 2。我对保存在服务器端的任何密钥都有同样的问题。如果您正在执行任何类型的哈希匹配或非对称解密, - 无论是签署 jwt 还是解密存储在 db 中的 cc 信息,您都必须有一个可由服务器上的代码访问的密钥。那你到底把它放在哪里??这是我找到的最佳答案:pcinetwork.org/forum/index.php?threads/… - 可能与 jwt 密钥一样安全。
-
jwt 令牌中的密钥是什么?我认为 jwt 令牌本身就是一个秘密。或者密钥可以是
RSAPrivateKey privateKey?? -
这是不久前问的,但也许有人会觉得它有用。就我而言,每个用户都有一个“密钥”。因此,每次用户登录时,我都会生成该密钥并将用户记录存储在数据库中。我使用该秘密验证令牌。注销后,我清除该值。这会自动使之前创建的其他令牌无效(这就是我需要的)。
标签: security authentication token jwt secret-key