刷新令牌对服务器性能的影响
Impact of Refresh Tokens on server performance
我正在研究一种在带有 Dotnet Core 后端的简单 SPA 上正确实现刷新和访问令牌的方法。我读得越多,就越担心它对我的影响
服务器性能,尤其是随着登录用户数量的增长。
以这个auth0 post and this specification为例,它清楚地表明我们每次创建访问令牌时都需要创建一个新的刷新令牌,因为恶意客户端试图重用刷新令牌。
In particular, authorization servers: MUST rotate refresh tokens on each use, in order to be able to detect a stolen refresh token if one is replayed (described in [oauth-security-topics] section 4.12)
既然我们希望限制访问令牌的过期时间(例如 10-20 分钟),我们需要保留我们生成的每个刷新令牌以识别旧刷新令牌的恶意 activity被重复使用。
这意味着每 20 分钟 n 用户访问我们的后端以刷新访问令牌并创建一个新的刷新令牌,因此 1k每 20 分钟有 1k 个请求的登录用户,我们的 api 也会检查每个用户提供的刷新令牌是否已经失效,如果没有,我们将保留新的刷新令牌。
因此,在用户登录一天后,我们保存了:24 * 60 / 20 = 72 个不同的刷新令牌 .. 现在我们检查每个用户与每个用户 ??
我是不是遗漏了什么,这如何扩展?
您实际上不需要存储所有创建的刷新令牌。您只需要一个已用令牌列表来检查您的用户尝试刷新的令牌是否被重复使用,并且由于您的刷新令牌应该像您的访问令牌一样具有到期时间,因此您也不需要存储令牌,即使用过的,比它们的寿命更长。
- 如果用户尝试使用有效的刷新令牌:它没有过期并且不在您使用的令牌列表中。干得好!
- 如果用户尝试使用过期的令牌:它已过期,因此无需担心重复使用,无需检查您的数据库以查找已使用的令牌。
- 如果用户尝试重复使用有效的刷新令牌:它在您的列表中。
所以虽然它确实随着用户数量的增加而扩展,但随着时间的推移它是稳定的并且不会超出比例(前提是你清除旧代币)。
还有其他事情需要考虑。如本 other auth0 post 中所述,在重用的情况下,您希望使整个令牌系列无效,而不仅仅是拒绝对重用令牌的一个用户(可能是合法用户)的访问。再一次,您不需要存储令牌系列中的每个令牌来跟踪需要无效的内容:您只需要向您的令牌添加一个系列标识符,将该系列标识符本身标记为无效以备重用, 如果它们属于无效的家族,则拒绝未来的刷新尝试。可以清除无效系列列表以及所有无效时间超过刷新令牌寿命的系列标识符。
在服务器请求方面,与其他授权方式(如 API 密钥或 HTTP 基本身份验证)相比,刷新令牌应该是一种净性能提升,因为对于您必须发出的每个刷新令牌,您您还可以获得 20 分钟的请求,您不必查询数据库来检查 API 密钥是否仍然有效,或者提供的密码是否正确(特别是因为良好的密码散列功能,如bcrypt 故意慢)。
我正在研究一种在带有 Dotnet Core 后端的简单 SPA 上正确实现刷新和访问令牌的方法。我读得越多,就越担心它对我的影响 服务器性能,尤其是随着登录用户数量的增长。
以这个auth0 post and this specification为例,它清楚地表明我们每次创建访问令牌时都需要创建一个新的刷新令牌,因为恶意客户端试图重用刷新令牌。
In particular, authorization servers: MUST rotate refresh tokens on each use, in order to be able to detect a stolen refresh token if one is replayed (described in [oauth-security-topics] section 4.12)
既然我们希望限制访问令牌的过期时间(例如 10-20 分钟),我们需要保留我们生成的每个刷新令牌以识别旧刷新令牌的恶意 activity被重复使用。
这意味着每 20 分钟 n 用户访问我们的后端以刷新访问令牌并创建一个新的刷新令牌,因此 1k每 20 分钟有 1k 个请求的登录用户,我们的 api 也会检查每个用户提供的刷新令牌是否已经失效,如果没有,我们将保留新的刷新令牌。
因此,在用户登录一天后,我们保存了:24 * 60 / 20 = 72 个不同的刷新令牌 .. 现在我们检查每个用户与每个用户 ??
我是不是遗漏了什么,这如何扩展?
您实际上不需要存储所有创建的刷新令牌。您只需要一个已用令牌列表来检查您的用户尝试刷新的令牌是否被重复使用,并且由于您的刷新令牌应该像您的访问令牌一样具有到期时间,因此您也不需要存储令牌,即使用过的,比它们的寿命更长。
- 如果用户尝试使用有效的刷新令牌:它没有过期并且不在您使用的令牌列表中。干得好!
- 如果用户尝试使用过期的令牌:它已过期,因此无需担心重复使用,无需检查您的数据库以查找已使用的令牌。
- 如果用户尝试重复使用有效的刷新令牌:它在您的列表中。
所以虽然它确实随着用户数量的增加而扩展,但随着时间的推移它是稳定的并且不会超出比例(前提是你清除旧代币)。
还有其他事情需要考虑。如本 other auth0 post 中所述,在重用的情况下,您希望使整个令牌系列无效,而不仅仅是拒绝对重用令牌的一个用户(可能是合法用户)的访问。再一次,您不需要存储令牌系列中的每个令牌来跟踪需要无效的内容:您只需要向您的令牌添加一个系列标识符,将该系列标识符本身标记为无效以备重用, 如果它们属于无效的家族,则拒绝未来的刷新尝试。可以清除无效系列列表以及所有无效时间超过刷新令牌寿命的系列标识符。
在服务器请求方面,与其他授权方式(如 API 密钥或 HTTP 基本身份验证)相比,刷新令牌应该是一种净性能提升,因为对于您必须发出的每个刷新令牌,您您还可以获得 20 分钟的请求,您不必查询数据库来检查 API 密钥是否仍然有效,或者提供的密码是否正确(特别是因为良好的密码散列功能,如bcrypt 故意慢)。