目前,访问令牌在 15 分钟后过期,并且存储在有效负载中的唯一信息是用户 ID。
每个用户都有一个可以在应用程序内使用的余额。我应该在每个请求上查询数据库,以便我可以提取余额吗?将其存储在有效载荷中会不安全吗?
目前,访问令牌在 15 分钟后过期,并且存储在有效负载中的唯一信息是用户 ID。
每个用户都有一个可以在应用程序内使用的余额。我应该在每个请求上查询数据库,以便我可以提取余额吗?将其存储在有效载荷中会不安全吗?
tl/dr:尽管您可以将余额存储在 JWT 中并且不会被篡改,但 JWT 中的余额在很多方面可能在技术上有效但仍然不正确。因此,您可能最好每次都检查数据库中的余额,并且您当然需要在进行任何交易之前检查它
JWT 有两种:
这些用例略有不同。如果您需要做的只是验证存储在 JWT 中的数据是否正确且未被篡改,那么 JWS 就可以了(假设您正确实施它并验证所有请求的签名)。因此,您可以将余额存储在 JWS 中,然后确认报告的余额就是您最初存储的余额。
如果您还想保持数据的私密性,那么您可以使用 JWE。加密还将保证数据不会被修改(同样,假设您正确实施了 JWE)。请注意,通常唯一有权访问 JWT 的人是最终用户,因此我们正在讨论将其保密 - 对于您的用例(h/t EdC)可能不是必需的。
因此,天平不会被篡改。
在任何一种情况下,您都应该在进行实际交易之前检查数据库的余额,因为:
余额可能仍然是错误的。如果在没有更新 JWT 的情况下进行了另一笔交易,或者出现了旧的 JWT(也称为重放攻击),那么您可能拥有一个余额不正确的有效 JWT。即使没有积极的攻击者,这种情况也很可能发生。考虑使用超过 1 个应用程序的用户。在您的假设场景中,如果余额存储在一台设备的 JWT 中,然后用户登录另一台设备并进行交易,会发生什么情况?第一个设备的 JWT 中的数据现在不正确,即使 JWT 本身有效且尚未过期。这只是可能发生有效但不正确的 JWT 的多种方式之一。
有许多可能的方法可以解决 JWT 中过时数据的问题,但最终这些修复可能比每次都检查数据库更有效。但是,这是最终取决于您的平衡行为!那里没有一个正确的答案。
是的,您应该在每个请求上查询数据库。使用 JWT 方法意味着您依赖客户端发送正确的 JWT。如果您建议在 JWT 上存储余额,那么我认为您的想法是每次余额更改时生成一个新的 JWT。问题在于信任客户端发送正确的 JWT。
例子
在每个请求上查询数据库将否定使用 JWT 的主要好处——您不必访问数据库。假设您正确使用 JWT,在其中存储信息是安全的。由于它是签名的,攻击者无法修改内容。
编辑:虽然签名确保有效负载没有被摆弄,但它不保证它仍然是最新的。请参阅Andy N 的非常好的答案。