【问题标题】:Race condition in JWTJWT 中的竞争条件
【发布时间】:2021-04-16 00:43:14
【问题描述】:

阅读了几篇关于在网站/应用程序中使用 JWT 进行登录/注销的教程,他们似乎都建议使用这种在有效负载数据上存储一些用户信息(如 id、名称等)的机制,例如(来自官方website):

{
  "id": 4,
  "name": "John Doe",
  "admin": true
}

然后将令牌存储在前端的某处,并将其包含在每个请求中(例如,在 Bearer 之后的 Authorization 标头中)。但是这种跟踪登录用户的形式可能会导致更改有效负载数据(如登录和注销)的操作出现严重的竞争条件。这是一个简单的场景:假设 id 为 4 的用户已经登录,并且包含用户 id 有效负载的令牌已经存储在前端。现在前端应用程序发送一些请求,并且按时间顺序执行以下操作:

Action JWT token stored in the frontend login status
Front end sends request A asking for some arbitrary action {id:4} logged in
Front end sends request B asking to logout {id:4} logged in
The response of request B comes, carrying token with payload {} which means user is logged out {} logged out
The response of request A comes carrying token with payload {id:4} (same as its corresponding request) {id:4} logged in!!!!!

因此,当用户退出时,它会在没有通知的情况下重新登录!这是因为请求 A 的响应令牌覆盖了令牌 B 的响应令牌!一般来说,这种在 jwt 有效负载上存储任何信息的分散机制可能会导致竞争条件,因为传入的令牌可以相互覆盖并且更改(例如登录状态)可能会丢失。我想我们需要在前端或后端做更多的事情。我是否遗漏了有关 JWT 的某些内容?

【问题讨论】:

    标签: authentication session jwt jwt-auth


    【解决方案1】:

    JWT 令牌仅在登录请求的响应时生成并返回。在其余的(操作)调用中,JWT 令牌仅发送到后端,客户端没有接收到新令牌并进行更新。注销时,客户端的令牌被清除。

    只有在登录和注销请求之间才会出现竞争条件。

    理想情况下,您不能删除 JWT 令牌,因为我们不会将其存储在后端。删除是真正的只有当它过期时。因此,此模型的修改版本将在后端维护所有已注销未过期令牌的列表,以提高安全性。这也有助于避免上述竞争条件。

    【讨论】:

    • 是的,正如你所说,我们需要做更多的事情,比如删除前端的令牌......但这意味着 JWT 无法存储会话信息,因为它们可能会发生变化。这违反了 JWT 官方网站 example,他们在 JWT 令牌中存储用户名(John Doe 像往常一样)。如果用户更新他的名字怎么办?
    • a 不删除,如果 JWT 令牌存储在服务器管理的 cookie 中(即设置了 httponly 标志的 cookie),那么只有在注销响应中 JWT 存储的 cookie 内容为空
    猜你喜欢
    • 2016-03-07
    • 2011-07-17
    • 2013-02-27
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2018-10-08
    相关资源
    最近更新 更多