【发布时间】: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