当前位置: 首页 > news >正文

Spring Boot整合JWT 实现双Token机制

目录

  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-key
  expiration: 7200 # 2小时
  header: Authorization

2.2 Token生成与解析

工具类实现

@Component
public class JwtUtils {
    // 注入配置参数
    @Value("${jwt.secret}")
    private String secret;
    
    // 生成Token
    public 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();
    }

    // 解析Token
    public Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }
}

2.3 拦截器实现

认证拦截器

public class JwtInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) {
        // 1. 检查白名单路径
        if (isWhiteList(request.getRequestURI())) {
            return true;
        }
        
        // 2. 获取并验证Token
        String 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);
    }
}

注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public 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

刷新接口实现

@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. 限流控制:接口请求频率限制

黑名单实现

@Component
public class TokenBlacklist {
    @Autowired
    private 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管理策略。

相关文章:

  • Oracle GoldenGate 全面解析
  • Description of a Poisson Imagery Super Resolution Algorithm 论文阅读
  • 管家婆实用贴-如何设置打印机共享
  • Vue.js 与 RESTful API 集成之处理 GET、POST 请求
  • Flutter_学习记录_状态管理之GetX
  • Spring Security 教程:从入门到精通(含 OAuth2 接入)
  • 利用JavaScript在网页中获取当前的时间并展现在网页上
  • 【算法day13】最长公共前缀
  • 接上一篇,C++中,如何设计等价于Qt的信号与槽机制。
  • TCP/IP四层网络模型
  • LeetCode hot 100 每日一题(10)——56. 合并区间
  • Chainlit 自定义元素开发指南:使用 JSX 和受限导入实现交互式界面
  • 软件工程:数据字典
  • 图解AUTOSAR_CP_WatchdogDriver
  • Python的类和对象(4)
  • Python函数默认参数为什么不能用可变对象
  • uniapp vue3项目定义全局变量,切换底部babar时根据条件刷新页面
  • Spring中Bean的自动装配
  • 电脑型号与尺寸
  • 大数据学习拓展——Minio安装与使用
  • 媒体:演员黄杨钿甜耳环事件仍有三大疑问待解
  • 张核子“限高”次日即被解除,前员工的执行款3个月后仍未到账
  • 南宁海关辟谣网传“查获600公斤稀土材料”:实为焊锡膏
  • 首届中国人文学科年度发展大会启幕,共话AI时代人文使命
  • 海外考古大家访谈|冈村秀典:礼制的形成与早期中国
  • 就规范涉企行政执法专项行动有关问题,司法部发布解答