是否应该对注销请求进行身份验证?

信息安全 验证 oauth jwt
2021-09-01 16:53:47

我已经实现了访问令牌和刷新令牌,没有身份验证服务器(我的 API 服务器也进行身份验证)。

  • 访问令牌:存储在客户端(本地存储)中。20 分钟后过期。
  • 刷新令牌:存储在客户端(本地存储)和服务器(数据库)中。3个月到期。
  • 刷新“窗口”为一周,因此该周内无需重新登录即可刷新令牌。
  • 3 个月后刷新令牌过期,因此用户必须重新登录。

当用户注销时,我从本地存储中删除访问和刷新令牌。但我也应该删除服务器上的刷新令牌,所以我必须/logout向服务器发出请求。

是否应该对该注销请求进行身份验证?

让我们说是的。问题是如果用户没有登录(即访问令牌已过期),并且刷新窗口已经过去(比如说,一周),那么无法执行自动刷新,所以他将被迫登录,以便他可以注销。奇怪的!

另一种方法是让该端点期望访问和刷新令牌对,但 1) 允许访问令牌过期,以及 2) 确保访问令牌仍然有效,并且刷新令牌既有效又是最新的。在这种情况下,从数据库中删除刷新令牌。

处理此问题的典型方法是什么?有没有我没有考虑过的优点/缺点?

3个回答

无需保护注销资源。

如果注销请求存在会话;它变得无效。否则它会被直接重定向到注销页面。

我认为用户请求注销与令牌到期之间存在差异。

简短的回答是您绝对必须对/logout端点进行身份验证,以防止攻击者强行注销您的所有用户。如果您不验证此端点,任何人都可以注销任何用户。因此这个端点必须受到保护。

对于访问令牌和刷新令牌都过期的情况——用户尝试访问一个页面,例如/account,您的后端检测到访问令牌已过期,然后它将重定向到刷新端点,例如/refresh

/refresh检测到刷新令牌也已过期,现在将用户重定向到/login页面。用户登录后,他们将获得新的刷新和访问令牌,一切都好起来了。

如果您保留所有活动刷新令牌的列表,那么您应该在第二次用户登录期间更新该列表,并且不需要单独/logout调用。但是,这些令牌列表通常仅在令牌验证后进行验证,如果令牌过期则不会。

我想知道为什么要保护或不保护注销端点?

我决定不保护端点,而是检查:访问令牌是否有效(即使已过期)然后撤销刷新令牌。

为什么:

  • access=current & refresh=current:这是一个正常的认证请求,所以撤销
  • access=expired & refresh=current:可以执行令牌刷新,所以只需撤销
  • access=expired & refresh=expired:用户无论如何都需要登录,所以撤销

  • access=invalid和/或refresh=invalid:令牌被黑/被盗,因此必须撤销

所以我能看到的所有路径都会导致撤销。只要访问令牌有效,即使过期,也只需撤销相应的刷新令牌即可。


所有这一切的替代方法是以通常的方式保护端点。但这会导致注销--> 刷新(失败)--> 登录--> 注销循环。我的方法避免了这种情况。