SpringBoot集成JWT无状态身份认证的方案详解

 更新时间:2025年11月18日 09:20:53   作者:t***L266  
本文介绍了如何在SpringBoot项目中集成JWT实现无状态身份认证,JWT由Header、Payload和Signature三部分组成,通过添加JJWT依赖,创建JWT工具类和认证拦截器,实现前后端的交互流程,需要注意安全性、性能优化和常见问题,感兴趣的朋友跟随小编一起看看吧

 SpringBoot集成JWT实现无状态身份认证实战

在现代Web应用中,身份认证是必不可少的安全环节。传统的基于Session的认证方式虽然简单易用,但在微服务架构和前端多平台场景下,面临着扩展性差和服务器存储压力大等问题。本文将介绍如何在SpringBoot项目中集成JWT(Json Web Token)实现无状态的身份认证方案。

 一、什么是JWT

JWT是一种开放标准(RFC 7519),定义了一种紧凑且自包含的方式,用于在各方之间安全传输信息作为JSON对象。JWT由三部分组成:

1. **Header**:包含令牌类型和使用的哈希算法

2. **Payload**:存放有效信息的负载部分

3. **Signature**:对前两部分进行签名,防止数据篡改

典型的JWT格式:`xxxxx.yyyyy.zzzzz`

 二、SpringBoot集成JJWT

首先,在pom.xml中添加JJWT依赖:

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>

创建JWT工具类`JwtUtils.java`:

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private long expiration;
// 生成token
public String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
return Jwts.builder()
.setClaims(claims)
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
// 解析token获取用户名
public String getUsernameFromToken(String token) {
SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
// 验证token是否有效
public boolean validateToken(String token) {
try {
SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}

 三、实现认证拦截器

创建JWT认证拦截器`JwtAuthenticationFilter.java`:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
// 如果请求头中没有token,直接放行
if (StringUtils.isEmpty(token)) {
chain.doFilter(request, response);
return;
}
// 验证token有效性
if (!jwtUtils.validateToken(token)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write("无效的Token");
return;
}
// 获取用户名并设置到SecurityContext中
String username = jwtUtils.getUsernameFromToken(token);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
}

配置拦截器注册:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}

 四、前后端交互流程

1. **登录流程**:

- 客户端发送用户名密码到`/api/auth/login`

- 服务器验证成功后生成JWT返回给客户端

- 客户端将JWT存储在本地(localStorage或cookie)

2. **后续请求**:

- 客户端在请求头中添加`Authorization: Bearer <JWT>`

- 服务器验证JWT有效性后处理请求

 五、注意事项

1. **安全性**:

- 必须使用HTTPS传输JWT

- 设置较短的过期时间,结合Refresh Token实现自动续期

- JWT一旦发出无法撤回,处理敏感操作应额外验证密码

2. **性能优化**:

- 避免在JWT中存储过多信息

- 可以考虑将部分用户信息缓存在Redis中

3. **常见问题**:

- 密钥泄露问题:定期更换密钥

- CSRF攻击:配合CSRF Token使用

通过本文介绍的方案,我们可以在SpringBoot项目中轻松实现基于JWT的无状态认证。相比传统Session验证,JWT方案更适合现代分布式系统的认证需求,具有诸多优势。

到此这篇关于SpringBoot集成JWT无状态身份认证的文章就介绍到这了,更多相关SpringBoot JWT无状态身份认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring boot udp或者tcp接收数据的实例详解

    spring boot udp或者tcp接收数据的实例详解

    这篇文章主要介绍了spring boot udp或者tcp接收数据,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • java微信支付功能实现源码

    java微信支付功能实现源码

    这篇文章主要给大家介绍了关于java微信支付功能实现源码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • java编写贪吃蛇小游戏

    java编写贪吃蛇小游戏

    贪吃蛇是经典手机游戏,既简单又耐玩。通过控制蛇头方向吃蛋,使得蛇变长,从而获得积分。今天我们就来用java来实现下贪吃蛇小游戏,有需要的小伙伴可以参考下
    2015-03-03
  • Java轻松实现将Excel文本替换为图片

    Java轻松实现将Excel文本替换为图片

    在日常工作和项目开发中,Excel作为数据展示和报告生成的利器,却也常常暴露出一些局限性,本文将展示如何使用Java将Excel工作表中的文本替换为图片,有需要的小伙伴可以了解下
    2025-09-09
  • tomcat在Linux环境下的安装与配置详细教程

    tomcat在Linux环境下的安装与配置详细教程

    这篇文章主要介绍了tomcat在Linux环境下安装与配置的相关资料,涵盖Java环境准备、下载解压、启动服务、部署项目及管理界面设置,适合开发测试环境搭建,需要的朋友可以参考下
    2025-05-05
  • 使用Logback日志保存到相对路径的操作

    使用Logback日志保存到相对路径的操作

    这篇文章主要介绍了使用Logback日志保存到相对路径的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 探讨Java中最常见的十道面试题(超经典)

    探讨Java中最常见的十道面试题(超经典)

    本篇文章是对Java中最常见的十道面试题进行了详细的分析介绍,需要的朋友参考下
    2013-07-07
  • Java集合案例之斗地主游戏

    Java集合案例之斗地主游戏

    这篇文章主要为大家详细介绍了Java集合案例之斗地主游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Java.toCharArray()和charAt()的效率对比分析

    Java.toCharArray()和charAt()的效率对比分析

    这篇文章主要介绍了Java.toCharArray()和charAt()的效率对比分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Java基础篇之对象数组练习

    Java基础篇之对象数组练习

    对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋给数组就行了,这篇文章主要给大家介绍了关于Java基础篇之对象数组练习的相关资料,需要的朋友可以参考下
    2024-03-03

最新评论