想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
去年关闭。
Improve this question
(从this thread产生,因为这实际上是一个问题,并不特定于NodeJS等)
我正在通过身份验证实现REST API服务器,并且已经成功实现了JWT token 处理,以便用户可以使用用户名/密码通过/ login端点登录,然后从服务器 secret 生成JWT token 并将其返回给客户。然后,在每个经过身份验证的API请求中,将 token 从客户端传递到服务器,然后使用服务器 secret 来验证 token 。
但是,我试图了解关于如何以及在多大程度上验证 token 的最佳实践,以构成一个真正安全的系统。 “验证” token 应该包含什么内容?可以使用服务器 secret 来验证签名是否足够,还是我还应该对照服务器中存储的某些数据来交叉检查 token 和/或 token 有效载荷?
基于 token 的身份验证系统仅与在每个请求中传递用户名/密码一样安全,只要获取 token 与获取用户密码同等或更困难。但是,在我看到的示例中,生成 token 所需的唯一信息是用户名和服务器端 secret 。这不是说假设一分钟内恶意用户获得了服务器 secret 知识,他现在就可以代表任何用户生成 token ,从而不仅可以访问一个给定的用户,而且如果密码为获得,但实际上是所有用户帐户?
这使我想到了以下问题:
1)JWT token 验证是否应仅限于验证 token 本身的签名,仅依靠服务器 secret 的完整性或通过单独的验证机制进行验证?
2)如果JWT签名验证是验证 token 的唯一方法,这意味着服务器密钥的完整性是切入点,那么应该如何管理服务器密钥?从环境变量读取并为每个部署的堆栈创建一次(随机化?)?定期更新或轮换(如果这样,如何处理在轮换之前创建但在轮换之后需要验证的现有有效 token ,如果服务器在任何给定时间保留当前和先前的 secret 就足够了) ?还有吗
当涉及到服务器 secret 受到威胁的风险时,我可能只是过于偏执,这当然是一个更普遍的问题,需要在所有加密情况下都解决...
最佳答案
我也一直在为应用程序使用 token 。尽管我绝不是专家,但我可以分享一些有关此事的经验和想法。
JWT的本质是完整性。它为服务器提供了一种机制,以验证提供给它的 token 是真实的并由服务器提供。通过您的 secret 生成的签名就是解决方案。因此,是的,如果您的 secret 以某种方式泄露,那么该人可以生成您的服务器认为是自己的 token 。仅由于签名验证,基于 token 的系统仍将比您的用户名/密码系统更安全。并且在这种情况下,如果有人反正拥有您的 secret ,则系统会处理其他安全问题,而不是制造伪造 token 的人(即使如此,仅更改 secret 也可以确保使用旧 secret 制作的任何 token 现在都无效)。
至于有效负载,签名只会告诉您提供给您的 token 与服务器发送 token 时的 token 完全相同。验证有效载荷内容对您的应用程序有效还是合适显然取决于您。
对于您的问题:
1.)以我有限的经验,最好使用第二个系统来验证 token 。简单地验证签名就意味着 token 是使用您的 secret 生成的。将所有创建的 token 存储在某种类型的数据库(redis,memcache / sql / mongo或某些其他存储)中是一种绝妙的方式,可确保您仅接受服务器已创建的 token 。在这种情况下,即使您的 secret 被泄露,也不会太重要,因为任何生成的 token 都将是无效的。这是我在系统上采用的方法-所有生成的 token 都存储在数据库(redis)中,并且在接受每个请求时,我在接受 token 之前先验证 token 是否在数据库中。这样,可以出于任何原因撤销 token ,例如以某种方式释放的 token ,用户注销,密码更改, secret 更改等。
2.)这是我经验不足的事情,而且由于我不是安全专业人员,所以我仍在积极研究中。如果您找到任何资源,请随时在此处发布!当前,我只是使用从磁盘加载的私钥,但是显然这与最佳或最安全的解决方案相去甚远。