如何使用spring boot jwt注销

Posted

技术标签:

【中文标题】如何使用spring boot jwt注销【英文标题】:How can logout using spring boot jwt 【发布时间】:2020-08-11 21:28:54 【问题描述】:

我正在使用这个例子https://dzone.com/articles/spring-boot-security-json-web-tokenjwt-hello-world 用于使用 json Web 令牌 (JWT) 创建 spring boot rest api。但我没有找到任何使用 io.jsonwebtoken maven 依赖项强制注销的 api。

我在 pom 中使用这个依赖:

groupId io.jsonwebtoken artifactId jjwt 0.9.1 版

任何人都可以告诉我这种依赖关系,是否提供任何注销或撤销令牌 api。如果没有,请提供使用此过程强制注销的任何解决方案。

【问题讨论】:

In this example, we will be making use of hard-coded user values for user authentication。通常,令牌机制没有注销,因为服务器从不创建会话......你可以做的是删除(你需要将它存储在某处并检查它是否存在......)/通过某些标准拒绝令牌。本文遵循Spring Boot + JWT + mysql JPA for storing and fetching user credentials.的指导 感谢@Valijon 的回复,我只想在注销时使用 jwt 使令牌无效。因为它不在服务器端维护会话。那么我们如何在不将令牌保存在数据库中的情况下解决从jwt强制注销的问题,因为如果我按照将令牌保存在数据库中并设置令牌黑名单。然后我们在每个服务器请求上检查令牌是否是黑名单。我认为这不是注销并签入所有令牌黑名单请求的正确方法。你能告诉我在spring boot rest full api中注销的任何其他过程或任何其他方法吗 注销意味着关闭会话,但是使用JWT和其他令牌机制,没有会话......没有任何解决方案可以满足您的要求。使用与会话相关的标准安全机制,然后您可以注销... 你的意思是 JWT 不提供任何东西来撤销令牌?如果这是真的,你能告诉我,我们的应用程序移动用户的 spring boot rest api 身份验证的任何其他过程。 @RakeshKumar 我也有同样的问题,你是如何找到解决方案的? 【参考方案1】:

我相信代币有有效期。您可以简单地缩短有效期,这样如果令牌被黑客入侵,那么它在到期后就没有用了

【讨论】:

【参考方案2】:

注销可以做几件事:

    通常,如果我们谈论单页应用程序,jwt 令牌存储在浏览器本地存储或会话存储中。因此,在这种情况下可以做的第一件事 - 从存储中删除令牌:

window.sessionStorage.removeItem("token") // 用于会话存储

window.localstorage.removeItem("token") // 用于本地存储

参考他们:https://developer.mozilla.org/ru/docs/Web/API/Window/sessionStorage https://developer.mozilla.org/ru/docs/Web/API/Window/localStorage

我的 Angular 示例:https://github.com/dmcheremisin/TodoApp/blob/master/frontend/src/app/service/jwt-authentication.service.ts

    但客户端可能会将此令牌存储在某处并手动提供。为避免长时间使用令牌,您应该设置较短的过期时间。例如,15 分钟。

如果您需要允许进一步使用令牌 - 请刷新它,否则拒绝。

刷新方法示例:

public String refreshToken(String token) 
    final Date createdDate = new Date();
    final Date expirationDate = calculateExpirationDate(createdDate);

    final Claims claims = getAllClaimsFromToken(token);
    claims.setIssuedAt(createdDate);
    claims.setExpiration(expirationDate);

    return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();

此代码 sn-p 来自我使用相同库 jjwt 的 repo: https://github.com/dmcheremisin/TodoApp/blob/master/backend/src/main/java/com/todo/app/util/JwtTokenUtil.java

    黑名单已注销令牌。我个人不喜欢这种方法,因为在多节点应用程序的情况下,您需要集中放置列入黑名单的令牌。创建 JWT 令牌是为了避免链接到具体 Web 服务器(节点)会话的会话。因此,您不能只将令牌存储在应用程序的一个节点中。

相关文章:https://medium.com/devgorilla/how-to-log-out-when-using-jwt-a8c7823e8a6

【讨论】:

感谢@Dmitrii 支持理解 jwt 令牌。实际上,我为 android 应用程序移动用户创建了一个带有 spring boot rest api 的后端项目。目前我在服务器端使用 jwt 和 spring boot 安全无状态会话。但我只是困惑,当移动用户从应用程序中按下注销时会发生什么。那么我们如何使用 jwt 令牌来处理这件事。请帮帮我。 嗨,@RakeshKumar。我不知道在 android 应用程序开发中是如何完成的。但我想在您的情况下,最简单的解决方案是从您的应用程序上下文(android 应用程序上下文)中删除令牌。令牌将丢失,用户将无法向 spring boot rest api 发送任何安全请求。因此,请在注销时删除令牌。 实际上,如果我使用此过程从上下文级别删除令牌,我担心令牌黑客攻击。如果有人复制此令牌并再次用于另一个 API 调用。这对应用程序用户有害。那么你能告诉我一些关于服务器端删除 jwt 令牌的事情吗?如果无法使用 spring boot jwt 从服务器端删除令牌,那么请告诉我服务器端的另一种令牌方法(如果有)。像spring boot oauth2(这个东西提供撤销令牌)。但我没有使用这个,因为我们必须为此需要一个身份验证服务器。所以如果你有任何其他方法,请与我们分享 我为这种情况提供了 2 号和 3 号。您可以限制令牌的到期时间并根据需要刷新。或者,您可以在注销时将令牌列入黑名单,但您应该使用集中式黑名单存储,以防多节点 spring boot api(具有负载平衡的多个后备服务器)。如果你只使用你的 api 的一个节点,那么你可以只在你的 spring boot api 中将令牌列入黑名单,而不用担心。 好的 @Dmitri,感谢您的支持并为您提供宝贵的时间“关于 JWT 令牌”。这对我们来说是非常有用的讨论。谢谢

以上是关于如何使用spring boot jwt注销的主要内容,如果未能解决你的问题,请参考以下文章

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

Spring Boot JWT Authentication:登录和注销后触发一个方法

如何在 Spring Security 无状态(jwt 令牌)中注销用户?

如何在 Spring Boot WebFlux 中使用 GET 请求注销

如何使用 Spring Boot 测试 jwt.*?

Spring Boot JWT 身份验证