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

JWT令牌安全实践详解

JWT令牌安全实践详解

一、JWT概述

JSON Web Token(JWT)是一种用于安全传输信息的开放标准(RFC 7519)。

1.1 JWT结构

┌─────────────────────────────────────────────────────────────┐ │ JWT Token │ ├─────────────────────────────────────────────────────────────┤ │ Header.Payload.Signature │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ {"alg":"HS256", {"sub":"123", HMACSHA256( │ │ "typ":"JWT"} "name":"John", base64Url(header). │ │ "exp":1704067200) + "." + │ │ base64Url(payload),│ │ secret) │ └─────────────────────────────────────────────────────────────┘

1.2 JWT组成部分

部分说明编码方式
Header算法和类型Base64Url
Payload声明信息Base64Url
Signature签名HMAC/RSA

二、JWT实现

2.1 创建JWT

import io.jsonwebtoken.*; import java.util.Date; public class JwtUtil { private static final String SECRET_KEY = "your-256-bit-secret-key"; private static final long EXPIRATION_TIME = 86400000; // 24小时 public static String generateToken(String userId, String username) { return Jwts.builder() .setSubject(userId) .claim("username", username) .claim("role", "admin") .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } }

2.2 验证JWT

public static Claims validateToken(String token) { try { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); } catch (JwtException | IllegalArgumentException e) { throw new RuntimeException("Invalid token", e); } }

2.3 刷新Token

public static String refreshToken(String token) { Claims claims = validateToken(token); claims.setIssuedAt(new Date()); claims.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)); return Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }

三、JWT安全配置

3.1 密钥管理

// 使用256位以上的密钥 private static final String SECRET_KEY = generateSecureKey(); private static String generateSecureKey() { SecureRandom random = new SecureRandom(); byte[] key = new byte[32]; // 256 bits random.nextBytes(key); return Base64.getEncoder().encodeToString(key); }

3.2 使用RSA非对称加密

// 生成RSA密钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); KeyPair keyPair = keyGen.generateKeyPair(); // 使用私钥签名 String token = Jwts.builder() .setSubject("user123") .signWith(keyPair.getPrivate(), SignatureAlgorithm.RS256) .compact(); // 使用公钥验证 Claims claims = Jwts.parser() .setSigningKey(keyPair.getPublic()) .parseClaimsJws(token) .getBody();

3.3 设置合理的过期时间

// 访问Token:短过期时间 private static final long ACCESS_TOKEN_EXPIRE = 15 * 60 * 1000; // 15分钟 // 刷新Token:长过期时间 private static final long REFRESH_TOKEN_EXPIRE = 7 * 24 * 60 * 60 * 1000; // 7天

四、安全最佳实践

4.1 Token存储策略

存储位置优点缺点适用场景
LocalStorage方便访问XSS风险单页应用
SessionStorage会话级存储页面切换丢失临时数据
HttpOnly CookieXSS安全CSRF风险传统Web
Memory最安全页面刷新丢失高安全场景

4.2 CSRF防护

// Spring Security配置 http.csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .ignoringRequestMatchers("/api/**") );

4.3 XSS防护

<!-- 设置HttpOnly和Secure标志 --> Set-Cookie: JWT=token; HttpOnly; Secure; SameSite=Strict

五、Token黑名单机制

5.1 基于Redis的黑名单

public class TokenBlacklist { private final StringRedisTemplate redisTemplate; private static final String PREFIX = "blacklist:"; public void invalidateToken(String token, long expireSeconds) { String key = PREFIX + token; redisTemplate.opsForValue().set(key, "true", expireSeconds, TimeUnit.SECONDS); } public boolean isBlacklisted(String token) { String key = PREFIX + token; return Boolean.TRUE.equals(redisTemplate.hasKey(key)); } }

5.2 拦截器验证

public class JwtInterceptor implements HandlerInterceptor { private final TokenBlacklist blacklist; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = extractToken(request); if (blacklist.isBlacklisted(token)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } // 继续验证token return true; } }

六、JWT vs Session对比

特性JWTSession
状态无状态有状态
存储客户端服务端
扩展性
安全性需额外处理相对安全
性能网络传输大服务器内存

七、安全检查清单

7.1 必做检查

检查项说明
使用HTTPS防止Token被窃取
设置过期时间限制Token有效期
避免敏感信息Payload是Base64编码,不是加密
使用强密钥256位以上密钥
验证签名防止Token被篡改

7.2 推荐检查

检查项说明
实现刷新机制定期轮换Token
实现黑名单支持主动注销
限制Token大小避免过大Payload
监控异常行为检测暴力破解

八、总结

JWT是一种强大的身份认证机制,但需要正确使用才能保证安全:

  1. 使用HTTPS:始终通过HTTPS传输Token
  2. 合理设置过期时间:访问Token短,刷新Token长
  3. 使用非对称加密:避免密钥泄露风险
  4. 实现黑名单机制:支持主动注销
  5. 存储在安全位置:根据场景选择存储方式

通过以上措施,可以构建安全可靠的JWT认证系统。

http://www.jsqmd.com/news/874226/

相关文章:

  • AI系列【仅供参考】:周末用笔记本搞点大事:手把手教学部署 1.5、7B 版本 DeepSeek 智能助手
  • 黄仁勋放话:AI基建要烧掉4万亿美元 谁买单?
  • LeetCode 930:和相同的二元子数组 | 前缀和与哈希表
  • 从微服务到 Agent 服务:架构思维的迁移
  • 微服务安全防护实战:OAuth2与JWT鉴权
  • 【带RL负载的全波桥式整流器】功能齐全的单相非控整流器(Simulink)
  • 运维系列虚拟化系列OpenStack系列【仅供参考】:创建 VXLAN - 每天5分钟玩转 OpenStack(111)部署 instance 到 VXLAN - 每天5分钟玩转 OpenSt
  • LeetCode 1314:矩阵区域和 | 二维前缀和
  • 3分钟解决Mac与Windows文件交换难题:Nigate免费NTFS读写工具完全指南
  • 吴恩达:2026年是AI的黄金时代?普通人如何抓住最后上车窗口?
  • 3分钟搞定Windows桌面整理:NoFences免费开源工具终极指南
  • AI Agent Harness Engineering 在房地产中的应用:智能推荐与价值评估
  • 敏感数据加密存储实战
  • 通过 TaoToken 用量分析功能优化模型选型与调用策略
  • SLAM技术路线收敛?不,多模态融合正在重启路线之争
  • 前缀和与差分进阶总结 | 技巧归纳与实战应用
  • Go语言CI/CD流水线实践
  • 【GO context 】上下文取消/超时的本质
  • 无语,Trae的AI编程想混过去啊,我就说了点重话:我只要结果,我需要一个成语接龙程序,这个程序能正确运行,可以通过验收!
  • 2026第三方配送平台选型指南:成都本地跑腿加盟/成都本地配送平台/成都第三方配送平台/成都聚合配送平台/成都自配送平台/选择指南 - 优质品牌商家
  • 2026泳池设计优质厂家推荐:泳池设计/洗浴厂家/洗浴工程/洗浴改造/洗浴施工/洗浴设备/温泉洗浴设计/游泳池改造/选择指南 - 优质品牌商家
  • 企业级条码处理方案:ZXing.Net在.NET生态中的架构实践与性能优化
  • 【Appium 系列】第18节-重试与容错 — 移动端测试的稳定性保障
  • 2026泳池建造厂家推荐:酒店洗浴、户外泳池、泳池工程、泳池水处理、泳池设备、洗浴厂家、洗浴工程、洗浴改造、洗浴施工选择指南 - 优质品牌商家
  • 锌钢护栏网技术解析:四川公路铁路护栏网、四川双边丝护栏网、四川围栏网、四川学校球场围栏、四川市政道路护栏网、四川牛栏围栏网选择指南 - 优质品牌商家
  • 2026年Q2四川应急物资厂家评测:应急消防设备厂家/应急物资厂家电话/抗洪抢险应急设备/消防工具厂家/消防智能设备/选择指南 - 优质品牌商家
  • 2026成都靠谱金属建材回收公司推荐:工厂废料回收/工地废料回收/库房物资回收/废旧机器回收/废铁回收/废铜回收/选择指南 - 优质品牌商家
  • 毕业论文神器!2026年必备AI论文软件榜单,免费版也能写合规初稿
  • 2026年Q2西南地区测绘仪租赁服务机构排行盘点:华测rtk/华测无人船/地形测量/大疆无人机/徕卡全站仪/手持扫描仪/选择指南 - 优质品牌商家
  • 2026年当下河北工程网格布实力厂商剖析与精准选型指南 - 2026年企业推荐榜