我应该将用户信息放在JWT令牌中,还是只需放置用户ID,然后从数据库中选择信息?

6
由于用户信息可以被管理员或其他人更改,而不是由用户自己更改,因此令牌用户信息(有效负载)未更新为包含在数据库中的信息。
但是我希望尽可能少地进行数据库请求,因此我考虑将用户信息存储在其令牌中。
我认为这是错误的,最好只存储他们的唯一ID,这是MongoDB中的索引和时间戳 - 这样用户就不会一遍又一遍地使用相同的令牌 - 他必须从服务器登录。
但是,然后我需要查询数据库,并且我希望尽可能少地进行查询。
我应该只用用户的ID查询数据库吗?
3个回答

4
如果您愿意公开与使用令牌的用户共享用户ID,则应将其包含在JWT中。但是,您不应在令牌中包含用户可能滥用系统中的任何信息,例如可能暴露底层实现细节的ID。
作为一个经验法则,如果您不会向用户提供存储在JWT中的数据,则不要将其存储在JWT中,因为用户可以解码Base64。
此外,根据您在客户端上存储JWT的方式,我建议限制存储敏感数据的数量,因为这些数据可以被运行在客户端上的任何JavaScript访问。

https://auth0.com/docs/security/store-tokens#web-storage-disadvantages

Web Storage 可以通过 JavaScript 在相同的域名下访问,因此您网站上运行的任何 JavaScript 都可以访问 Web Storage,并且因此容易受到跨站脚本 (XSS) 攻击。


当你说“滥用你的系统”时,是指类似于用户输入的注入吗?无论如何,我都会验证用户的输入。你所说的“不给用户数据”是什么意思?最终我会返回用户的信息。 - Raz Buchnik
从攻击者的角度来考虑,我可以使用 xxx 数据进行什么操作?您可能正在使用它进行 id 枚举等操作... 因此您正在公开实现细节。我见过有些人在 JWT 中存储一些疯狂的东西,所以我建议小心使用。还要取决于您将 JWT 存储在何处以及将其用作会话 cookie 还是本地存储中。然后,您可能需要开始加密数据。 - Kevin Smith
我不明白你的意思。用户只会收到一些无关紧要的信息,他没有解密令牌中内容的钥匙。 - Raz Buchnik
更新的答案包括更多信息和链接,等等。 - Kevin Smith
1
@Raz:“他没有密钥解密令牌中的内容”:只有当您使用加密的JWT aks JWE时才是真的,JWT的通常形式是签名JWT aka JWS,它只是编码的并且可以被每个人阅读(请参见https://jwt.io)。 - jps
哦,好的,我正在使用加密。 - Raz Buchnik

4

将ID存储起来可能是一个更好的想法,因为用户数据可以像你所说的那样进行修改。 此外,JWT中的大型有效负载会导致在几乎每个网络请求中发送额外的字节。 在大多数情况下,您不需要整个用户数据,ID在大多数情况下都足够好。 因此,我建议将ID(必要时可能还有其他字段)存储在JWT中,而不是所有用户数据。


0
我建议您只发送userId,也许还有token的创建和过期日期。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接