Spring Boot中REST接口集成JWT认证的核心是通过拦截、解析、校验、放行四环节实现无状态鉴权;需引入JJWT依赖、配置密钥与过期时间、封装JwtUtil工具类、自定义JwtAuthenticationFilter并插入Security链,禁用Session且明确放行路径。

Spring Boot 中 REST 接口集成 JWT 认证,核心是用无状态 Token 替代 Session,实现前后端分离场景下的安全鉴权。关键不在“加依赖”,而在于拦截、解析、校验、放行四个环节的闭环设计。
添加必要依赖与基础配置
选用 io.jsonwebtoken:jjwt-api + jjwt-impl + jjwt-jackson(推荐 0.12.x 版本),避免老版 jjwt 的反射异常问题。不建议混用 auth0/java-jwt,因 Spring Security 生态更适配 JJWT。
在 application.yml 中定义密钥和过期时间:
jwt: secret: your-32-byte-secret-key-here # 必须≥32字节(HS256要求) expire-time: 3600 # 单位:秒,建议≤2小时
编写可复用的 JwtUtil 工具类
封装生成、解析、校验逻辑,避免重复代码。重点注意:
- 使用
SecretKeySpec显式构造密钥,防止字符编码歧义 - 载荷(Claims)中只存必要字段(如
userId、role),不存密码、手机号等敏感信息 - 校验时必须检查
exp(过期)、nbf(生效前)、签名三要素
示例生成方法:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
public static String generateToken(Long userId, String role) {
return Jwts.builder()
.subject(userId.toString())
.claim("role", role)
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}自定义 JwtAuthenticationFilter 拦截请求
继承 OncePerRequestFilter,在每次请求进入 Controller 前执行 Token 提取与认证:
- 从
Authorization: Bearer xxx头中提取 token - 调用
JwtUtil.validateToken()解析并校验有效性 - 若合法,构造
UsernamePasswordAuthenticationToken并设入SecurityContextHolder - 若非法,直接返回 401,不继续链路
该 Filter 需插入在 UsernamePasswordAuthenticationFilter 之前,确保登录后 Token 才生效。
配置 Spring Security 放行与保护规则
禁用 Session,启用无状态模式,并明确声明哪些路径无需认证:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/login", "/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}注意:hasRole("ADMIN") 会自动匹配 ROLE_ADMIN,无需手动加前缀;角色信息需在 UserDetails 或 JWT 载荷中提供。

















