JWT刷新令牌策略

6
我在一篇关于使用JWT进行React身份验证的博客(此处)中看到了以下设置:访问令牌过期时间为15分钟,刷新令牌过期时间为1个月;每10分钟,客户端调用/refreshToken端点,检查刷新令牌是否仍然有效(否则用户将显示登录屏幕)。
在服务器上,/refreshToken端点正确检查refreshtoken是否过期,具有refreshtoken负载中id的用户仍然存在且有效(即:传递的refreshtoken存在于其refreshTokens数组中)。如果一切正常,将生成新的访问令牌,并与响应一起发送。
到目前为止,一切都很好。但是,在返回响应之前,还会生成一个新的refreshToken,并将其替换为用户的refreshTokens数组中的旧令牌...我认为这种策略存在缺陷,因为这样用户将永远不会看到他的登录过期,即使刷新令牌(在此示例中为一个月)过期...
我进行了一些测试(将1个月的值降低到30分钟),实际上用户授权永远不会过期...强制注销用户并删除其refreshTokens数组显然是有效的,但当刷新令牌因年龄过期时,我希望能够注销用户。
我想知道我的理解是否正确(服务器上的refreshToken端点不应刷新refreshToken,而只应刷新accessToken),或者我是否遗漏了什么。
在@Ghero的评论后进行更新: 我明白你的观点...但如果不更新它的到期时间,为什么要刷新令牌?
然而,博客中的代码用于更新refresh token:
    const jwt = require("jsonwebtoken");

    exports.getRefreshToken = (user) => {
      const refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET, {
        expiresIn: eval(process.env.REFRESH_TOKEN_EXPIRY),
      });
      return refreshToken;
    };

    // REFRESH_TOKEN_EXPIRY is set to 30 days

看起来它总是将到期日期推迟30天。这样它就永远不会过期了...

1个回答

8

将刷新令牌在每次使用时进行更换是当前的最佳实践。

使用一次性刷新令牌意味着,如果刷新令牌被盗并多次使用(由您和黑客),则令牌服务可以检测到并自动注销用户,从而保护用户免受攻击。

有一个最大时间,即30天等,刷新令牌有效期限。但这通常也是您可以配置的内容。根据您使用的服务,有不同的刷新令牌生命周期策略。下面的图片展示了IdentityServer如何处理刷新令牌: enter image description here


请查看我的更新答案。 - Tore Nestenius
抱歉,我不明白。我正在配置刷新令牌的最大有效时间。它是30天。 现在我将其设置为30分钟,仅用于测试目的。 我可以确认,如果每次调用刷新令牌端点时都会刷新刷新令牌,它将永远不会过期...这就是我的测试所证实的,刷新令牌在30分钟后不会过期(因此在30天后也不会过期...),用户将永远登录,除非在服务器上手动阻止...我想这不是最佳实践。我肯定是漏了什么,但我不知道是什么... - MarcoS
假设您的服务器配置了30天的刷新令牌过期时间。客户端每十分钟请求一次新的刷新令牌。会发放一个新的刷新令牌,但是过期时间不会更新(新的刷新令牌继承“原始”刷新令牌的过期时间)。因此,在原始令牌发放后30天,无论发放多少次新的刷新令牌,客户端都将被提示登录。 - Ghero
但是一个永不过期的会话实现是否可接受? - MarcoS
好吧,我想永远也可以,这完全取决于应用程序的类型。例如,如果您将Twitter连接到Instagram,则希望该关系永久存在,直到您撤销它,因此在这种情况下,一个永不过期的刷新令牌就足够了;而如果只是为了登录某个网站进行工作/业务,那么您可能希望用户界面会话受到限制。 - Tore Nestenius
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接