Spring Boot JWT - 如何实现刷新令牌和注销 REST-API

Posted

技术标签:

【中文标题】Spring Boot JWT - 如何实现刷新令牌和注销 REST-API【英文标题】:Spring Boot JWT - How to implement Refresh Token and Logout REST-API 【发布时间】:2021-03-11 13:44:10 【问题描述】:

我们决定从 Basic-Auth 切换到 JWT,因为 session-id 存储在内存中,有时会导致拍摄时内存消耗过多- 关闭我们的 Spring-Boot 服务器,该服务器为 Twitterandroid 移动应用提供服务。

但是对于我们的移动用例,我们有一些关于 JWT 的问题:

访问令牌应该存在多长时间? 刷新令牌应该存在多久? 如何通过使用户的access-tokenrefresh token 无效来注销用户? (对于注销我们已经删除了移动应用端的令牌,但是如果令牌被某人窃取并且仍然有效怎么办?)

【问题讨论】:

【参考方案1】:

我的意思是看起来你应该只是使用会话。 JWT 并不是一个简单的替代品。它们具有特定的功能,并且由于某种原因,它们已被嵌入作为任何身份验证系统的某种自动访问。

根据您的描述(将基本身份验证提升为更安全和现代的身份验证系统),您应该使用会话。 很好的 Cookie 会话。

我会更详细地说明原因,但要总结一下:

A) 如果您只使用传统的基于 cookie 的会话,您可以控制会话,而不会奇怪地粘在“banlist”表和 JWT 的额外架构上.

B) 它们经过试验和测试,浏览器将保证它们的安全!会话 cookie 可以设置为“安全”和“仅限 http”。人们将 JWT 放置在许多奇怪的地方,包括浏览器的本地/会话存储,只是等待一个顽皮的 js 注入广告来吸收它们。 JWT,就像 SessionID 一样,应该 位于仅限 Http、安全且同站点的严格 Cookie 中

因此,当浏览器非常满意时,您也可以只使用会话 ID 并在没有奇怪的前端状态管理的情况下继续生活,并在使用会话 Cookie 时为您安全地执行此操作。

C) 传统会话易于实施。更难理解它们如何/为什么与所有 SameSite/HttpOnly/CORS/Secure 部分一起工作......但是一旦理解,实现起来就容易了 99 倍,并且当 Spring 框架已经为您完成了 99% 时,需要更少的代码.

我的意思是确定编写自己的 JWTAuthTokenAuthFilter 并实现 JWTAuthenticationProviderJWTCreationService 和 `JWTAutoRefreshFilter...以及您梦寐以求的任何其他东西...只需要一个会话。 Spring 用 20 行经过良好测试的代码来完成。

总结一下: 我的意思当然是正确实施的 JWT 是安全的……只是也许它们并不总是最适合工作的工具。

阅读:

Stop Using JWTs for Sessions

当然,JWT 是有用的。他们是为了在客户端到达他们的 API 端点之前让第 3 方知道“是的,这是我认识的人”。或者说让您的一台服务器与您的另一台服务器通信......或让客户的服务器与您的服务器通信,甚至您的服务器与另一家公司通信:

JWT Auth - Best Practices

【讨论】:

【参考方案2】:

我会尽力回答你的问题

How long should an access token live?

您可以轻松配置到期时间,这取决于您的要求。 一般来说,尽量保持简短。

How long should the refresh token live?

以上适用于刷新令牌,条件是刷新令牌通常比访问令牌寿命更长,原因很明显。

How to logout a User by invalidating his access-token and refresh token? 

这部分可能有点棘手。

您不能在创建令牌后手动使其过期。因此,您不能像使用会话那样在服务器端使用 JWT 注销。

可以实现一些选项,例如

当用户执行注销操作或被入侵时。有一个黑名单来存储无效令牌,直到它们的初始到期日期。您将需要为每个请求查找数据库,但存储应该更少,因为您将存储在注销和到期时间之间的令牌。您可以通过将黑名单保存在内存中而不是 DB 中来提高效率。 在声明对象 JWT 中存储客户端 IP 地址。验证令牌时,您可以检查此客户端的 IP 地址是否相同。您可以根据需要对其进行优化,例如使用 User-Agent 和客户端 IP。 最糟糕的重置用户凭据或 JWT 令牌组件会生成一个新的,它会自动使所有现有的无效。

添加一些链接以获得更深入的细节

Invalidate JWT Token

Destroy JWT Token

【讨论】:

以上是关于Spring Boot JWT - 如何实现刷新令牌和注销 REST-API的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + OAuth + JWT + MySQL 刷新令牌第二次不起作用

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

如何使用 JWT 在 Spring Boot 中获取 Refresh Token

如何在 Spring Boot 微服务架构中使用 Keycloak 实现 JWT?

Spring Boot 中 JWT 的最佳实践是啥?

如何在 Spring Boot 后端使用 jwt 令牌实现注销功能(使用休息端点)