首页
Preview

Spring Boot使用JWT的REST API身份验证最佳实践(2022年)

1. 概述

在本教程中,我将解释如何使用JWT(JSON Web Tokens)实现生产就绪的基于令牌的REST API身份验证。我们将进一步使用这些令牌来标识我们在API的HTTP请求中的操作用户。对于本教程,我们将使用MongoDB来持久化我们的用户数据,你可以选择任何你喜欢的数据库。

2. 什么是JWT?

JSON Web Token(JWT)是一个编码字符串,我们将在这种情况下用它来标识我们的用户。 JWT由三部分组成,由句点(“.”)分隔:

  • 头部:它包含签名算法,例如SHA256。
  • 载荷:它包含我们的用户数据。
  • 签名:为了验证消息在传输过程中未被更改,使其更加安全。

将所有三个组合在一起,我们的JWT看起来像这样xxxxx.yyyyy.zzzzz。要了解有关JWT的更多信息,请访问- https://jwt.io/

3. 项目初始化

我们将使用Spring Initiailizr来初始化我们的Spring Boot项目。为了方便起见,我添加了5个依赖项,你可以根据项目需求进行微调。

生成并将项目导入你喜欢的IDE。还要记得在application.properties文件中添加数据库属性。

spring.data.mongodb.database=your_db_name_here spring.data.mongodb.port=27017

4. 其他依赖项

你将不得不添加以下依赖项以在项目中使用JWTcommons-lang3是可选的,我个人使用它的各种实用程序类。

对于基于maven的项目:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency><dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency><dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency><dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

对于基于gradle的项目:

dependencies {
    implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2',
             'io.jsonwebtoken:jjwt-jackson:0.11.2',
             'org.apache.commons:commons-lang3:3.0'
}

5. 项目结构

我们将遵循MVC模式,请参阅以下项目结构。

6. 配置

WebSecurityConfig.java中,我们将通过扩展WebSecurityConfigurerAdapter类来修改默认的spring security功能。在这里,我们将定义我们的HTTP请求过滤器和未经身份验证的用户的默认响应。它将作为所有HTTP请求的中间件。

在上面的configure(HttpSecurity httpSecurity)方法中,我们已经定义了允许以/auth路由开头的所有请求,这是我们将添加我们的身份验证控制器的地方。如果请求未经授权,我们的API将抛出一个401错误消息。

7. 请求过滤器

JwtRequestFilter.java中,我们将定义我们在前一章节中提到的API中间件中的请求过滤器。为此,我们将扩展OncePerRequestFilter,Spring保证它仅针对给定请求执行一次。

在这个doFilterInternal()方法中,我们将从请求头中获取JWT令牌并处理它,通过验证并从令牌的有效负载中获取用户名。进一步地,如果令牌有效,我们将从数据库中获取用户并将其添加到SecurityContextHolder中,我们可以在任何服务中进一步使用它来执行各种与用户相关的操作。

JwtTokenUtil.java中,我们将执行所有JWT令牌相关的操作,例如生成新令牌和验证给定令牌。

8. 模型和存储库

我们将在这里使用Lombok框架快速创建我们的User.java模型。它完全是可选的,但这是我定义模型类的最喜欢的方式。毕竟,生命太短暂,无法编写getter和setter。

我们将编写我们的UserRepository.java接口,并定义一个方法来从用户名中获取用户详细信息。

9. UserDetailsService

JwtUserDetailsService.java类中,我们将通过实现UserDetailsService接口来自定义默认的spring security获取用户的方式。

10. 控制器

最后但并非最不重要的是,我们将定义控制器以与我们的API通信。

AuthenticationController.java将处理用户登录和注册。在这两个路由中,我们将生成JWT令牌并将其发送到用户的响应中。

响应我们注册请求的示例:

你可以将响应中的此令牌保存在客户端(反应式Web或移动应用程序)的本地存储中,并稍后在API的受保护路由中使用此令牌。如果我们提供无效凭据给我们的登录请求,我们将获得带有错误代码401的响应:

现在是时候实际使用我们的JWT令牌来标识与HTTP请求相关联的用户了。以下代码段将帮助你在项目的任何地方获取经过身份验证的用户:

Authentication authentication = SecurityContextHolder
                .getContext().getAuthentication();
String username = authentication.getName();

为测试,我们将定义UserController.java。在这里,你可以获取我们在请求过滤器中添加的用户SecurityContextHolder。当我们在授权头中发送新创建的JWT令牌时,我们将获得以下适当的响应:

11. 结论

我们看到了如何为REST API实现基于令牌的身份验证以及各种神奇的框架来使生活更轻松。

本教程的完整代码已提交到我的Github存储库。不要忘记点击星标按钮:p

感谢你阅读本文,请在评论区提供宝贵的反馈。

原始发布在 https://blog.iamprafful.com.

译自:https://iamprafful.medium.com/spring-boot-rest-api-authentication-best-practices-using-jwt-2022-fd3d7ab61d3

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论