OAuth2:收到新的访问令牌后刷新令牌是否应该失效?
我目前正在开发一个遗留应用程序,该应用程序在某种程度上松散地实现了 OAuth2 流程。简而言之,当用户使用用户名/密码登录时,他会收到访问/刷新令牌对。访问令牌将在 20 分钟后过期,而刷新令牌的有效期为 180 天。
现在,当客户端由于访问令牌过期而收到 HTTP 401 Unauthorized 时,它将使用刷新令牌来获取新的访问/刷新令牌对。同时,我们使后端数据库中的旧令牌对失效(我们只需删除该条目)。
这存在一些重大问题,因为我们的客户端是移动应用程序,有时可能会发生客户端未收到我们服务器的响应的情况。因此,在我们的后端保存新的令牌对(客户端由于网络问题等原因而无法收到该令牌对)之后,客户端不再可以获得新的令牌对,因为他仍然只知道旧的(现已无效)刷新令牌。
我想知道我们所做的是否正确,或者我们是否实际上不应该从数据库中删除旧的刷新令牌,只要它们没有过期。或者我们应该记住用户的最后 1 或 2 个刷新令牌,这样即使创建了一个新令牌,如果客户端没有收到我们服务器的响应,他仍然可以使用旧令牌再次尝试一两次刷新令牌。
或者我们应该在获取新的访问令牌时永远不发送新的刷新令牌并始终使用相同的刷新令牌?
是否有任何最佳实践可供遵循,或者这都是个人喜好?我的意思是,我们不可能是第一个遇到移动客户端因网络问题而失去响应问题的人,对吗? :)
I currently work on an legacy app which somewhat loosely implements an OAuth2 flow. In short, when the user logs in with username/password, he receives an access/refresh token pair. The access token expires after 20 minutes whereas the refresh token has a lifetime of 180 days.
Now when the client gets a HTTP 401 Unauthorized due to an expired access token, it will use the refresh token to obtain a new access/refresh token pair. At the same time, we invalidate the old token pair in our backends database (we simply delete the entry).
This has some major issues since our clients are mobile apps and it sometimes can happen that a response from our server is not received by the client. So after our backend saves the new token pair, which the client doesn't receive due to for example network problems, the client no longer can get a new token pair because he still only knows about the old - now invalid - refresh token.
I was wondering if what we are doing is correct or whether we actually should never remove old refresh tokens from the DB as long as they are not expired. Or should we for example remember the last 1 or 2 refresh tokens for a user so even if a new one was created, if the client doesn't receive the response from our server, he can still try one or two times again with the old refresh token.
Or should we simply never send out new refresh tokens when obtaining a new access token and always use the same refresh token?
Is there any best practice to follow or is this all personal taste? I mean we can't be the first ones to run into this issue of mobile clients loosing responses due to network issues, right? :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
测量移动连接发生情况
当出现移动连接问题时,我预计刷新令牌授予
请求
会失败。请求成功而响应
未能到达客户端(在这么小的时间窗口内,例如200毫秒)感觉非常像边缘情况。我的目标是确保围绕服务器端发生的事情进行良好的生产日志记录,以便您可以更清楚地了解确切的原因。否则很容易得出错误的结论。
轮换刷新令牌
从安全角度来看,首选行为是在重复使用旧令牌时撤销用户的所有令牌。但是,OIDC 规范表明这可能会导致可用性问题在某些设置中,在这种情况下,
其他措施
可能是合适的。确切的行为是特定于提供商的 - 一些授权服务器存储并标记旧的刷新令牌,并可能允许它们在针对客户端应用程序配置的一段时间内重复使用。
安全性与可用性
如果处理高价值数据,我会使用更安全的选项,但如果移动消费数据不是特别敏感,那么使用非旋转刷新令牌可能是一个合适的措施。
可靠的应用
在某些情况下,OAuth 客户端在使用刷新令牌时会收到 401,除了您提到的情况之外,还有其他可能的原因:
应用程序应始终可靠地编码以处理此问题,例如:
error
响应字段中包含 401 或invalid_grant
值,用户必须重新进行身份验证请注意,重新身份验证有时是单点登录事件。要查看其外观,您可以运行我的 演示单页应用程序 并单击 < code> 使刷新令牌过期,然后
重新加载数据
。摘要
在分布式系统世界中,您无法始终保证 180 天内不重新登录。在接下来的步骤中,我的偏好是正确识别故障的原因和频率,并查看是否可以提高客户端应用程序代码的可靠性。
MEASURING MOBILE CONNECTIVITY OCCURRENCES
When there are mobile connectivity problems, I would expect the refresh token grant
request
to fail. For the request to succeed and theresponse
to fail to reach the client (in such a small time window, eg 200ms) feels very much like an edge case.I would aim to ensure good production logging around what is happening server side, so that you can be clearer about exact causes. It is easy to jump to the wrong conclusions otherwise.
ROTATING REFRESH TOKENS
The preferred behaviour from a security viewpoint is to revoke all tokens for the user when an old one is reused. However, the OIDC Specs indicate that this can cause usability problems in some setups, in which case
other measures
may be appropriate.Exact behavior is provider specific - some Authorization Servers store and flag old refresh tokens and may allow them to be reused for a time period configured against the client application.
SECURITY v USABILITY
If dealing with high worth data I would use the more secure option, but if mobile consumption data is not especially sensitive, using non-rotating refresh tokens might be an appropriate measure.
RELIABLE APPS
In some cases OAuth clients will get a 401 when using a refresh token, and in addition to the case you mention, there are other possible causes:
Apps should always be coded reliably to deal with this, eg:
invalid_grant
value in theerror
response field, the user must re-authenticateNote that re-authentication is sometimes a single sign on event. To see how this looks, you can run my Demo Single Page App and click
Expire Refresh Token
, thenReload Data
.SUMMARY
You cannot always guarantee no re-logins for 180 days in a distributed systems world. In terms of next steps, my preference would be to properly identify the cause and frequency of failures, and to see if reliability could be improved in the client application's code.
我正在努力将 oauth 2 添加到我们正在构建的 API 中,所以我还没有遇到这个特定问题,但我知道这可能会成为我们的问题。我读过一种解决方法,您可以将其过期时间调整为当前日期之前几分钟,而不是简单地撤销/删除已使用的刷新令牌。基本上是一个小的宽限期。如果客户端未能收到包含先前请求的更新令牌的响应,这将为客户端提供重新使用它的机会。
Fitbit 就是一个例子,他们实际上做了类似的事情,为撤销的令牌提供 2 分钟的宽限期
https://community.fitbit.com/t5/Web-API-Development/Refresh-token-amp-network-timeout/td-p/1102761
我不确定它今天是否仍然适用因为上面的帖子是6年前的了。
I'm working on adding oauth 2 to an API we are building, so I haven't run into this particular issue yet but I am aware that it might become a problem for us. I've read about one workaround where instead of simply revoking/deleting a used refresh token, you would adjust its expiration to just a few minutes ahead of the current date. A small grace period basically. This gives the opportunity for a client to re-use it if they failed to receive a response with the updated tokens from a previous request.
One example of this is Fitbit, where they actually do something similar by giving revoked tokens a 2 minute grace period
https://community.fitbit.com/t5/Web-API-Development/Refresh-token-amp-network-timeout/td-p/1102761
I am not sure though if it still applies today because the post above was from 6 years ago.