如何以及为啥使用 refresh_token 处理 jwt 令牌过期,还有另一种选择吗? [关闭]
Posted
技术标签:
【中文标题】如何以及为啥使用 refresh_token 处理 jwt 令牌过期,还有另一种选择吗? [关闭]【英文标题】:How and why handle jwt token expiration with refresh_token, is there another alternative? [closed]如何以及为什么使用 refresh_token 处理 jwt 令牌过期,还有另一种选择吗? [关闭] 【发布时间】:2020-11-19 03:37:50 【问题描述】:我有两场战争:app.war
(struts web app)和rest.war
(classic rest api)。
app.war
通过用户登录app.war
成功后生成的jwt令牌访问rest.war
。
当用户使用a.war
时,需要通过a.war
的jsp用jwt令牌发送ajax调用从rest.war
获取一些数据。
jwt token的过期时间为15分钟,而app.war
的会话超时时间为1小时。
但是,如果 jwt 令牌已过期,即使弹出要求用户再次登录,用户仍然可以访问app.war
。
还有一种选择:使用access_token
和refresh_token
,如果access_token
过期,则使用refresh_token
获取新的access_token
和refresh_token
。
对于这种方法,我有一些疑问:
首先,为什么要使用两个令牌?因为我认为它们是相同的,只是refresh_token
比access_token
寿命更长并使用refresh_token
来获得新的access_token
,那么为什么不只是access_token
并将其过期时间设置得更长呢?
第二,access_token
和refresh_token
的生成算法是不是一样,只是过期时间不一样?
第三,如果客户端使用token执行了多次api调用(同步和异步),如果其中一次调用返回401(token过期)如何处理?
【问题讨论】:
我不知道为什么它被关闭了。我认为它只关注一个问题:jwt token expired。 【参考方案1】:如您所说,refresh_token 是处理 jwt 过期的推荐替代方法。
为什么要使用两个令牌?
因为使用两个令牌(access_token 和 refresh_token)是世界级公司(google、azure、amazon 等)使用的经过验证的策略,它们信任 OAuth 2.0 授权框架
https://www.rfc-editor.org/rfc/rfc6749它是互联网工程任务组 (IETF) 的产物,而后者又是:互联网工程任务组 (IETF) 是一个开放的标准组织,它开发和推广自愿性互联网标准,特别是构成互联网协议套件。
您可以使用严格遵守其specification 的 oauth2 框架,创建并混合关注您的自定义需求或开发具有新概念的新框架
那么为什么不只是 access_token 并将其过期时间设置得更长呢?
Oauth2 规范不推荐使用不可过期的令牌。标记词本身意味着一个可过期的东西。如果它没有过期,我们可以使用密码。
例如,让我们想象一个需要令牌来下载一些用户信息的移动应用。如果令牌没有过期,小偷可以窃取移动应用程序,输入并访问用户信息。但由于令牌意味着到期,小偷可能有时间限制的访问权限。此外,用户在窃取时令牌可能是revoked,因此小偷无法访问。
通常当令牌过期时,会强制登录。但是有一些要求,用户不想每 3600 毫秒再次登录和登录。因此,refresh_token 有助于不打扰我们的用户并无需人工登录即可获得新的 access_token。现在,如果 refresh_token 没有过期会怎样?我们可以创建几个月或几年的访问令牌吗?这就是为什么 refresh_token 也必须过期
access_token和refresh_token的生成算法是一样的,只是过期时间不同?
我实现了一种安全服务器,并使用了相同的算法,但过期时间不同。但是我添加了一个额外的声明来区分它们:
How to differentiate refresh_token from access_token at validation stage in security server?多次调用需要access_token
在这种情况下,如果在每次用户登录时更新令牌,您将拥有一个可以使用 3600 毫秒的 access_token。
之后,您的用户是一种机器人(或者是您网络的功能/要求)并开始使用多种表单,这些表单对附加 access_token 的 rest api 执行多次调用。
如果我们在 3601ms,在下一次从 web 调用 api 时,api 必须返回 403 错误并显示经典的弹窗:Session expired, click here to login...
如果您的要求是避免此弹出窗口,您可以选择以下方法之一:
使用刷新令牌更新令牌时出现 403 错误。在这种情况下,您可以使用axios-retry 来处理错误重试。 登录后,启动异步任务以在小于令牌到期时间的间隔内更新令牌。在我们的示例中为 3400 毫秒。因此,来自您的网络的 api 调用永远不会失败建议
在后端层执行 access_token 和 refresh_token 交换,而不是在前端 (ajax) 层。
因此攻击者永远不会知道您的端点来获取令牌或刷新它们。
【讨论】:
感谢您的详细回答。你说Perform access_token and refresh_token exchange in your backend layer, not in frontend (ajax) layer.
,什么意思?你的意思是access_token
和refresh_token
不应该存储在用户客户端中,这样前端(ajax)就不需要发送它们?
不知道为什么关了,如果关了不知道赏金能不能分配给你。对此感到抱歉。
我试图改善你的问题。我认为这是一个有效的方法,可以帮助其他人了解refresh_token
的工作原理,但里面有几个问题:s以上是关于如何以及为啥使用 refresh_token 处理 jwt 令牌过期,还有另一种选择吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Google api refresh_token null 以及如何刷新访问令牌
为啥 context.startActivity(intent) 没有启动活动以及如何在 android 中处理异常?
使用带有 OpenID Connect 提供程序的 spring-security-oauth2 客户端时如何访问“id_token”和“refresh_token”?
jwt中为什么用refresh_token去刷新access_token,直接把access_token的有效期设置长一点不行吗?