Spring Boot整合JWT 实现双Token机制

news/2025/3/19 1:59:26/

目录

  1. JWT核心概念解析
  2. Spring Boot整合步骤
    • 2.1 基础环境搭建
    • 2.2 Token生成与解析
    • 2.3 拦截器实现
  3. 企业级增强方案
    • 3.1 双Token刷新机制
    • 3.2 安全防护策略
  4. 常见问题与解决方案

1. JWT核心概念解析

1.1 Token的三重使命

  • 身份凭证:替代Session实现无状态认证
  • 信息载体:存储用户基础信息(如userid、roles)
  • 安全屏障:数字签名防止数据篡改

1.2 JWT结构示例

Header
{"alg": "HS256","typ": "JWT"
}Payload
{"sub": "123456","name": "John","iat": 1516239022
}Signature
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

2. Spring Boot整合步骤

2.1 基础环境搭建

依赖配置

<!-- pom.xml -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>

配置文件

# application.yml
jwt:secret: your-256-bit-encryption-keyexpiration: 7200 # 2小时header: Authorization

2.2 Token生成与解析

工具类实现

java">@Component
public class JwtUtils {// 注入配置参数@Value("${jwt.secret}")private String secret;// 生成Tokenpublic String generateToken(UserDetails user) {return Jwts.builder().setSubject(user.getUsername()).claim("roles", user.getAuthorities()).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)).signWith(SignatureAlgorithm.HS256, secret).compact();}// 解析Tokenpublic Claims parseToken(String token) {return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}
}

2.3 拦截器实现

认证拦截器

java">public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 1. 检查白名单路径if (isWhiteList(request.getRequestURI())) {return true;}// 2. 获取并验证TokenString token = request.getHeader(jwtProperties.getHeader());if (!jwtUtils.validateToken(token)) {throw new UnauthorizedException("无效的访问凭证");}// 3. 注入用户信息Claims claims = jwtUtils.parseToken(token);request.setAttribute("userId", claims.getSubject());return true;}private boolean isWhiteList(String uri) {return Arrays.asList("/api/login", "/api/refresh").contains(uri);}
}

注册拦截器

java">@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor()).addPathPatterns("/api/**").excludePathPatterns("/api/auth/**");}
}

3. 企业级增强方案

3.1 双Token刷新机制

流程图解

Client Server 登录请求(账号+密码) AccessToken(2h)+RefreshToken(7d) 携带AccessToken请求 返回业务数据 loop [正常访问] 携带RefreshToken请求刷新 返回新AccessToken 重新登录 alt [AccessToken过期] [RefreshToken过期] Client Server

刷新接口实现

java">@PostMapping("/refresh")
public Result refreshToken(@RequestParam String refreshToken) {if (redisTemplate.hasKey(refreshToken)) {String username = redisTemplate.opsForValue().get(refreshToken);UserDetails user = userService.loadUserByUsername(username);String newAccessToken = jwtUtils.generateToken(user);return Result.ok().data("accessToken", newAccessToken);}throw new BusinessException(600, "刷新令牌已失效");
}

3.2 安全防护策略

五层防御体系

  1. 传输加密:强制使用HTTPS
  2. 存储安全:前端使用HttpOnly Cookie
  3. 自动续期:Access Token有效期≤2小时
  4. 黑名单:登出Token立即失效
  5. 限流控制:接口请求频率限制

黑名单实现

java">@Component
public class TokenBlacklist {@Autowiredprivate RedisTemplate<String, String> redisTemplate;// Token加入黑名单(有效期剩余时间)public void addToBlacklist(String token) {Date expiration = jwtUtils.getExpirationFromToken(token);long ttl = expiration.getTime() - System.currentTimeMillis();redisTemplate.opsForValue().set(token, "invalid", ttl, TimeUnit.MILLISECONDS);}
}

4. 常见问题与解决方案

问题现象根本原因解决方案
签名验证失败密钥不一致或Token被篡改统一密钥管理(配置中心)
Token突然失效服务器时间不同步部署NTP时间同步服务
高并发下认证超时RSA算法性能瓶颈切换为HS256算法
无法强制下线已登录用户无状态特性导致结合Redis维护短期Token黑名单

总结:JWT为现代分布式系统提供了优雅的认证解决方案,但实际落地时需综合考虑安全、性能、用户体验等多维度因素。建议结合具体业务场景选择合适的Token管理策略。


http://www.ppmy.cn/news/1580210.html

相关文章

基于CNN的多种类蝴蝶图像分类

基于CNN的多种类蝴蝶图像分类&#x1f98b; 基于卷积神经网络对64992786张图像&#xff0c;75种不同类别的蝴蝶进行可视化分析、模型训练及分类展示 导入库 import pandas as pd import os import matplotlib.pyplot as plt import seaborn as sns import numpy as np from …

Python 解析器安装指南(Mac / Windows / Linux)

本文档提供在 macOS、Windows 和 Linux 系统上安装 Python 解析器的详细流程。 1. 安装包下载 1.1 Python 下载官网 所有系统安装包 官网地址 系统类型访问地址Machttps://www.python.org/downloads/macos/Linuxhttps://www.python.org/downloads/source/Windowshttps://www…

使用kubeadm方式以及使用第三方工具sealos搭建K8S集群

目录 kubeadm方式: 一、安装要求 二、环境准备 二、安装Docker、kubeadm、kubelet 1、安装Docker &#xff08;1&#xff09;首先配置一下Docker的阿里yum源 &#xff08;2&#xff09;然后用yum 方式安装docker &#xff08;3&#xff09;配置Docker镜像加速器 &#…

解决 HTTP 请求中的编码问题:从乱码到正确传输

文章目录 解决 HTTP 请求中的编码问题&#xff1a;从乱码到正确传输1. **问题背景**2. **乱码问题的原因**2.1 **客户端编码问题**2.2 **请求头缺失**2.3 **服务器编码问题** 3. **解决方案**3.1 **明确指定请求体编码**3.2 **确保请求头正确**3.3 **动态获取响应编码** 4. **调…

DC/DC开关电源学习笔记(十四)Buck-Boost升降压电路仿真与应用案例

Buck-Boost升降压电路仿真与应用案例 1.升压CCM模式仿真(输入12V → 输出-24V)2.降压CCM模式仿真(输入24V → 输出-12V)3.实际应用案例Multisim仿真Buck-Boost电路的步骤说明,分为升压CCM模式和降压CCM模式两部分。 1.升压CCM模式仿真(输入12V → 输出-24V) 电路参数设计…

概率论的基本知识

逆概率还不懂&#xff0c;改天再想想。 联合概率 联合概率&#xff08;Joint Probability&#xff09; 是概率论中的一个重要概念&#xff0c;用于描述多个随机变量同时取某些值的概率。联合概率可以帮助我们理解多个变量之间的关系。

数据卷笔记

使用数据卷 # 语法&#xff1a;主要是这个-v 类似-p $ docker run -it -v 主机目录:容器内目录# run一个centos容器&#xff0c;并使用目录挂载 # /home/ceshi&#xff1a;主机home目录下的ceshi文件夹 映射&#xff1a;centos容器中的/home # 将容器里边的home目录挂载到lin…

缓存及其问题解决

目录 缓存的使用缓存的3大问题缓存穿透&#xff08;cache penetration&#xff09;什么是缓存穿透Why does cache penetration occur?&#xff08;如何产生的&#xff1f;&#xff09;The hazard of cache penetration(缓存穿透的危害) 如何解决缓存穿透问题解决1:缓存空对象(…