node.js - 为什么要在服务器数据库中存储 JWT 的刷新令牌?存储访问令牌会更好吗?
问题描述
我目前正在构建一个 Node.js 应用程序并尝试使用 JWT 来处理会话。在我见过的每个实现中,它refresh-token
都存储在一个快速的数据库中,比如redis
. 当令牌过期时,客户端发送refresh-token
来获取新的access-token
,然后服务器检查 是否refresh-token
在数据库中,然后生成一个新的令牌。
但是既然refresh-token
必须是服务端生成的,不可篡改,而且我们还可以检查是否过期,为什么还要存储呢。如果是这样,logout
那么我们不能只将user_id
已登录的人存储在数据库中而不存储refresh-token
.
我也在考虑存储最新的access-token
而不是refresh-token
inredis
作为user_id
. 原因是我们access-token
只会在前一个过期时生成一个新的。所以下面的场景不可能发生,
- 用户登录、获取
access-token
和refresh-token
. - 立即刷新他们的令牌,而前一个令牌仍然有效。
- 注销,并使用他们的旧访问令牌。
由于大多数实现仅access-token
在注销期间将客户端提供的黑名单,我相信如果客户端使用 REST API,这种情况是可能的。
那么存储 , 有什么用refresh-token
,并且存储access-token
会以任何方式有益。有关应用程序的更多信息,
- 我
redis
用于登录用户,并列入黑名单access-token
(在注销期间提供)。 - 我将
refresh
和access
令牌都存储在 httpOnly cookie 中,并将access
令牌作为不记名令牌发送。 refresh-token
在刷新访问令牌时在 POST 正文中发送。- 我没有使用
https
解决方案
让我回答你的每一个问题:
- “但是既然
refresh-token
必须是服务端生成的,不可篡改,而且我们也可以检查是否过期,为什么还要存储”:
刷新令牌意味着有很长的过期时间(可能是几个月),这样用户就不必经常登录应用程序(尤其是在移动应用程序的情况下)。因此,如果恶意人员盗取用户的刷新令牌,用户的受保护信息将长期暴露。如果发生这种情况,一个相当安全的应用程序应该有机制来检测用户 IP 地址的突然变化并报告这些变化。现在,如果用户确认他的帐户中存在奇怪的行为,则有必要撤销他的所有刷新令牌以保护他的信息,为此,需要控制某个用户拥有的刷新令牌,所以它们必须被存储。
- “如果是这样,
logout
那么我们不能只将user_id
已登录的人存储在数据库中而不存储refresh-token
“:
您需要同时存储“user_id”和刷新令牌,以便您可以控制某个“user_id”的所有刷新令牌(如上所述)。如果您只想存储登录用户的“user_id”(不存储刷新令牌),我不知道您将如何检查用户是否有权更新访问令牌而无需让用户登录。
- “我也在考虑存储最新的
access-token
而不是refresh-token
......”:
- 通过这样做,您将失去 JWT ( https://restfulapi.net/statelessness )提供的“无状态”方法的优势,因为您正在存储它们的状态。如果你真的想要这样的东西,最好使用像会话这样的“有状态”方法。
- 我看不出这样做的理由。假设您有一个连接到 RESTful API 的 Web 应用程序和一个移动应用程序,如果用户同时登录这两个应用程序,他将拥有多个有效的访问令牌和刷新令牌,因此用户同时拥有多个有效令牌是完全正常的时间。
- 如果用户注销,只需从他的设备中删除访问令牌和刷新令牌,此外,从数据库中删除刷新令牌。对访问令牌使用较短的过期时间(15 分钟很常见),因此您无需存储它们,因为它们会很快过期。而已。
推荐阅读
- c# - 如何使用 Mathf.Lerp 更改对象的平滑位置?
- reactjs - 如何在 React Native 中使用 fetch
- javascript - 如何根据 Angular 中的值显示/隐藏项目?
- javascript - 是否有任何方法可以解决顶点图表中的标记问题
- floating-point - “p”在浮点数的指数十六进制表示法中代表什么
- upgrade - 当 Storm 客户端从 0.10 升级到 1.1.0 时,Storm 拓扑部署失败并出现 IllegalArgumentException
- php - 如何将其他数据传递给 Laravel Socialite 中的回调方法?
- logstash-configuration - 使用 Logstash 配置文件添加小时数
- java - 引用 Jar 到日志文件的所有消息 + 设置日志文件编码为 UTF-8 以显示日文字符 (Log4j2)
- android - Android + ObjectBox 搜索查询问题