Java Spring JWT与刷新令牌工作流程问题

10

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

目前为止,我已经完成了以下步骤:

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

问题如下:

  • 我已将授权令牌设置为具有声明:type = auth,而将刷新令牌设置为带有声明:type = refresh。区分这两个令牌的最佳方法是什么。
  • 步骤3中的错误应该是什么(而不是未经授权),以将其与没有有效令牌的请求区分开来?
  • /token/refresh当前不要求身份验证。 这样做是否合适?
  • /token/refresh端点应该是带有标头的POST、带有参数的POST还是带有标头的GET?
1个回答

16

如何区分这两个令牌的最佳方法。

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

第三步应该是什么错误(而不是未经授权),以将其与没有有效令牌的请求区分开来?

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

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

不需要进行身份验证。

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

通常,GET端点应该是只读的,不会改变任何资源。 POST和PUT端点用于更改。在这种情况下,我将使用带参数和专用URL的POST,例如/token/refresh。


1
非常感谢。如果我不想将刷新令牌存储在数据库中,有没有其他方法可以实现? - D.Tomov
1
当然可以将刷新令牌表示为JWT。但有一个问题需要注意:JWT的过期日期是“铁板钉钉”的,只要4小时就会失效。但是,在许多情况下,您希望尽快使刷新令牌失效。例如1:显式注销->用户按下“注销”按钮。例如2:您希望立即禁止该帐户,并且不允许用户再使用刷新令牌。例如3:刷新请求看起来可疑->它来自不同的用户代理、不同的国家... - ygor
3
您可以在 https://github.com/ygor-sk/stackoverflow/tree/master/q53220918-jwt-refresh-token-workflow 查看完整示例。 - ygor
非常感谢。 - D.Tomov
@ygor 很棒的答案,感谢提供示例。然而,在示例中,将JWT令牌传递给任何需要令牌的端点都会返回401错误。这可能是什么原因? - DvixExtract

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