从 JWT 令牌中隐藏内部用户 ID



有一个REST API服务正在开发中,它通过内部SQL数据库为用户提供不同的搜索方法,并发出请求。数据库包含多个表,每个表都有一个 user_id 列,该列是 User 表中 id 列的引用键(唯一整数、主键)。这很重要。

当用户从客户端应用程序登录时,他将获取 JWT 令牌,其中包含带有用户 ID 值的"sub"部分。然后,当用户调用其中一个 API 方法时,他只提供 JWT 令牌,因此 API 从"sub"获取用户 ID,并向相应的表发出搜索请求。由于每个表都有一个user_id列,因此无需在 SQL 查询中对 User 表进行连接(如果我们在响应中不需要用户信息)。

问题是公开内部用户 ID 是一种不好的做法,可能会导致安全/业务问题。所以我正在考虑隐藏它。现在我看到以下选项:

  • 将用户 ID 更改为字符串列(使用顺序 GUID),但这对我们的系统来说是一个巨大的重大更改

  • 具有附加ext_user_id列 (GUID) 的现有用户表,并在 JWT 令牌中使用此值。缺点是之后每个 SQL 查询都将"连接"到 User 表以获取用户 id 值。

  • 保持数据库原样,但使用 JWE 令牌而不是 JWT。缺点是每个 API 请求都会进行令牌解密,这可能会影响性能。

也许还有另一种选择?还是这些方法中的一种方法比其他方法更具优势(实际上除了第一种方法)?

基本上我认为

这些是你的选择。

您专注于性能。对于解决方案 2 和 3,您必须比较 SQL 查询/联接的开销,以获取用户 ID 和 JWE 令牌的解密

JWE解密时间将始终基本相同,对称密钥可能是几毫秒的处理器时间。但是,数据库查询需要磁盘访问,并取决于其他因素:记录数、联接数、磁盘访问时间等。如果不详细了解问题,就不可能给您一个绝对的衡量标准。我建议你凭经验衡量每个案例的开销,并评估它是否对你来说是个问题

除了性能之外,我建议通过隐藏 ID 来评估附带问题

您是否需要客户端知道 REST API 中的 ID?

例如,如果你有一个资源使用如下所示的 ID  

/user/{userId}/getSomeData

JWE 将没有用,因为您需要以任何方式提供标识符

您是否需要客户端解码 JWT?

如果使用 JWE,客户端无法解码,因为它没有解密密钥

在服务器中需要多少个位置才能将 GUID 转换为 ID?

您需要针对每个查询进行查询,或者在入口点的筛选器中执行常规转化查询

最新更新