带有刷新令牌工作流问题的 Java Spring JWT

Posted

技术标签:

【中文标题】带有刷新令牌工作流问题的 Java Spring JWT【英文标题】:Java Spring JWT with refresh token workflow questions 【发布时间】:2019-04-12 17:44:50 【问题描述】:

我对使用 Java Spring 的 API JWT 刷新令牌工作流有一些疑问。

到目前为止我有这个:

    用户登录到 /users/login - 如果成功,则返回带有 2 个标头的响应授权和刷新。其中包含 2 个令牌 - 一个有效期短 30 分钟,一个有效期较长 4 小时。 然后他可以使用授权标头访问所有其他端点。 如果在某个时候访问端点,他的令牌已过期,他会收到一个错误 (UNAUTHORIZED)。 并且必须使用他获得的刷新令牌向 /token/refresh 发出请求。

问题:

我已将其设置为授权令牌具有声明:type=auth 和 刷新令牌有一个声明:type=refresh。最好的方法是什么 区分这两个令牌。 第 3 步中的错误应该是什么(而不是未经授权)才能将其与没有有效令牌的请求区分开来 /token/refresh 当前不要求进行身份验证。应该吗? /token/refresh 端点应该是带有标头的 POST、带有参数的 POST 还是带有标头的 GET。

【问题讨论】:

【参考方案1】:

区分这两个标记的最佳方法是什么。

刷新令牌根本不必是 JWT。我更喜欢简单地生成一个随机的字母数字字符串。刷新令牌不携带任何附加信息。它需要查找数据库以确认刷新令牌的有效性。您可以通过它们在您的请求中出现的位置来区分它们。授权令牌(访问令牌)应出现在您选择的标头中。

步骤 3 中的错误应该是什么(而不是未经授权)才能将其与没有有效令牌的请求区分开来

发送 401 Unauthorized 正是这样做的方法。 401 告诉客户端,他现在无法访问该资源,但他可以采取行动,以便再次访问该资源(登录/刷新令牌)。另一边的 403 会告诉客户端,资源不属于他,他将不得不请求权限,例如通过联系管理员

/token/refresh 当前不要求进行身份验证。应该吗?

不,不需要认证。

/token/refresh 端点应该是带有标头的 POST、带有参数的 POST 还是带有标头的 GET。

一般来说,GET 端点应该是只读的,不能改变任何资源。 POST 和 PUT 端点用于突变。在此,我将使用带有参数和专用 URL 的 POST,例如/token/刷新

【讨论】:

非常感谢。如果我不想将刷新令牌存储在数据库中,有没有办法做到这一点? 是的,当然,您可以将刷新令牌表示为 JWT。但是有一个问题。 JWT 的到期日期是“一成不变的”。 4小时后失效。但是,有很多情况下,您希望尽快使刷新令牌过期。示例一:显式注销 -> 用户按下“注销”按钮。示例二:您想立即禁止该帐户并且不允许用户再使用刷新令牌。示例三:刷新请求看起来很可疑 -> 它来自不同的用户代理、不同的国家... 您可以在github.com/ygor-sk/***/tree/master/…查看完整示例 非常感谢 @ygor 很好的答案,感谢您的示例,但是在示例中将 jwt 令牌传递给任何需要令牌的端点返回 401,这可能是什么原因。

以上是关于带有刷新令牌工作流问题的 Java Spring JWT的主要内容,如果未能解决你的问题,请参考以下文章

带有刷新令牌的 Spring Google OAuth2

Spring 5,401 返回后带有 Google 刷新访问令牌的 OAuth2

带有访问/刷新令牌的 Spring Boot OAuth2 SSO 未正确存储在数据库中

Spring OAuth2刷新令牌刷新访问令牌后更改

如何在 Spring Boot 中实现刷新令牌

带有 JWT 令牌的 Spring Security 在每个请求上加载 spring UserDetails 对象