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

JWT的说明和使用

JWT的说明和使用

JWT(JSON Web Token)是一种基于开放标准(RFC 7519),用于在网络应用间以JSON格式安全传递声明信息(如用户身份、权限等)。它通过数字签名保证信息的完整性和真实性,常被用于用户认证和信息传递,尤其适合前后端分离、分布式系统中的身份验证场景。

一、JWT的核心特点

1.自包含:Token本身包含用户身份等关键信息(无需频繁查询数据库)
2.无状态:服务器无需存储Token信息,减轻服务器负担(适合分布式系统)
3.跨域支持:基于JSON格式,可在不同语言、不同域之间传递
4.安全性:通过签名机制(HMAC、RSA等)防止信息被篡改

二、JWT的结构(三部分组成)

JWT由3个Base64编码的部分组成,用.分隔,格式为:header.payload.signature

1.Header(头部)

示例(JSON):
{ 	"alg":"HS256", 	"typ":"JWT" 
}
作用:生命Token的类型(typ:"JWT")和签名算法(如HS256、RS256) 
处理:JSON被Base64编码后作为第一部分,如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

2.Payload(载荷)

1. 作用:存储需要传递的声明信息(用户数据、过期时间等),分三种类型: 	标准声明(推荐但不强制): 	iss:签发者exp:过期时间(时间戳,单位秒) 	sub:主题 	aud:受众 	iat:签发时间jti:Token唯一标识(用于防止重放攻击) 自定义声明:业务相关信息(如userId:123、role:"admin")
2. 注意:Payload仅经过Base64编码(未加密),不要存放敏感信息(如密码) 
示例(JSON):
{"sub":"1234567890","name":"John Doe","iat":1516239022,"exp":1516242622,"userId":1001
}
处理:JSON被Base64编码后作为第二部分,如:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjIsInVzZXJJZCI6MTAwMX0

3.Signature(签名)

作用:对Header和Payload进行签名,防止数据被篡改 生成规则:1.用Header中指定的算法(如HS256)2.签名公式:
signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secretKey)
示例:用密钥secret对前两部分签名后,得到第三部分:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c完整JWT示例,三部分拼接后:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjIsInVzZXJJZCI6MTAwMX0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

三、JWT工作流程(以用户登录为例)

1.用户登录:用户输入账号密码,发送登录请求到服务器
2.服务器验证:验证通过后,生成JWT(包含用户ID、过期时间等信息),并返回给客户端
3.客户端存储:客户端(浏览器/APP)将JWT存储在localStorage、sessionStorage或Cookie中
4.后续请求:客户端每次请求时,在HTTP头Authorization中携带JWT(格式:Bearer<token>)
5.服务器校验:服务器接收请求后,解析JWT并验证签名5.1 签名有效且未过期:解析Payload中的用户信息,处理请求5.2 前端无效或已过期:返回401(未授权),要求重新登录

四、Java实现JWT(基于jjwt库)
1.引入依赖(Maven)

<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>

2.JWT工具类(生成、解析、验证)

import io.jsonwebtoken.*;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;public class JwtUtils {// 密钥(生产环境需放在配置文件,且足够复杂)private static final String SECRET_KEY = "your-256-bit-secret-key-which-should-be-very-long-and-secure";// 过期时间:1小时(单位毫秒)private static final long EXPIRATION_TIME = 3600000;// 生成 Tokenpublic static String generateToken(Long userId, String username) {// 自定义声明(可选)Map<String, Object> claims = new HashMap<>();claims.put("userId", userId);claims.put("username", username);return Jwts.builder().setClaims(claims)  // 放入自定义声明.setIssuedAt(new Date())  // 签发时间.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))  // 过期时间.signWith(getSignInKey(), SignatureAlgorithm.HS256)  // 签名算法和密钥.compact();  // 生成 Token}// 从 Token 中获取指定声明(如 userId)public static <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {final Claims claims = extractAllClaims(token);return claimsResolver.apply(claims);}// 解析 Token 获取所有声明private static Claims extractAllClaims(String token) {return Jwts.parserBuilder().setSigningKey(getSignInKey())  // 用密钥解析.build().parseClaimsJws(token).getBody();}// 验证 Token 是否有效(未过期且签名正确)public static boolean isTokenValid(String token) {try {// 解析时会自动校验签名和过期时间,若无效则抛出异常Jwts.parserBuilder().setSigningKey(getSignInKey()).build().parseClaimsJws(token);return true;} catch (JwtException | IllegalArgumentException e) {// 签名无效、过期、格式错误等都会触发异常return false;}}// 获取签名密钥(转换为 SecretKey 类型)private static SecretKey getSignInKey() {// 密钥需与签名算法匹配(HS256 要求密钥至少 256 位)byte[] keyBytes = SECRET_KEY.getBytes();return Keys.hmacShaKeyFor(keyBytes);}
}

3.使用示例(登录与验证)

// 1. 登录成功后生成 Token
@PostMapping("/login")
public R login(@RequestBody LoginDTO loginDTO) {// 验证账号密码(省略)User user = userService.verify(loginDTO.getUsername(), loginDTO.getPassword());// 生成 JWTString token = JwtUtils.generateToken(user.getId(), user.getUsername());return R.success(token);
}// 2. 接口访问时验证 Token(可通过拦截器实现)
@Component
public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 从请求头获取 TokenString token = request.getHeader("Authorization");if (token == null || !token.startsWith("Bearer ")) {response.setStatus(401);return false;}token = token.replace("Bearer ", "");// 验证 Token 有效性if (!JwtUtils.isTokenValid(token)) {response.setStatus(401);return false;}// Token 有效,解析用户信息存入请求(供后续接口使用)Long userId = JwtUtils.extractClaim(token, claims -> claims.get("userId", Long.class));request.setAttribute("userId", userId);return true;}
}

五、JWT优缺点

优点 
无状态:服务器无需存储Token,减轻分布式系统的会话共享压力 	
跨平台:基于JSON格式,支持多语言、多终端
自包含:减少数据库查询(用户信息直接从Token解析)     缺点
无法主动吊销:Token一旦生成,在过期前始终有效(除非服务器维护黑名单)
Payload未加密:Base64编码可被破解,不可存放敏感信息  
过期时间固定:无法动态延长有效期(需客户端主动刷新Token)

六、使用建议

1.密钥安全:密钥必须保密且足够复杂(HS256推荐256位以上),避免硬编码
2.短期有效期:设置较短的过期时间(如1小时),并提供Token刷新机制
3.不存敏感信息:Payload仅放非敏感数据(如用户ID,角色)
4.HTTPS传输:防止Token在网络中被窃取

JWT是目前前后端分离架构中身份认证的主流方案,合理使用可大幅提升系统的灵活性和安全性

http://www.dtcms.com/a/569151.html

相关文章:

  • MFC - 使用 Base64 对图片进行加密解密
  • Git+SSH 实现控制分支的提交权限
  • 网站建设选择题网站的内容建设
  • 怎么用自己电脑做网站服务器刚做淘客没有网站
  • CUDA C++编程指南(3.1)——使用NVCC编译
  • Numpy学习总结
  • 可梦AI获首批企业好评,蜜糖网络入驻共启AI短剧工业化
  • 笔记跨设备无缝切换?Joplin+cpolar让多设备同步更自由
  • Swift 6.2 列传(第四篇):enumerated () 的 “集合神功”
  • PDF 全文翻译开发实现思路:挑战、细节与工程化解决方案
  • 算法解析:从杨辉三角到几何查询的编程实践
  • 数学基础---刚体变换(旋转矩阵与平移矩阵)
  • 找别人建网站去哪里设计网址合集
  • 宁波网站建设费用wordpress启用注册
  • 我的第一个开源项目IOT-Tree Server-实际项目使用介绍
  • 蓝牙钥匙 第41次 紧急情况处理场景下的汽车数字钥匙系统:全方位应急方案设计与实现
  • Nestjs框架: gRPC微服务通信及安全实践全解析
  • 朴朴超市小程序分析
  • 济南物流公司网站建设金华建设工程网站
  • visual basic 从入门到精通 IT9网络学院VB编程系列培训教程
  • 厦门汽车充电站建设报备网站免费ppt模板下载中国风
  • 操作系统期中考试
  • 陕西建设集团韩城公司网站怎样创建基本的网站
  • 每日两题day33
  • 【解决】Failed to remove partition 1 from system: 设备或资源忙
  • Android通过SQL查询trace分析进程启动线程总数量
  • 超轻量级 AI 网安工具
  • 【C++】封装红黑树实现map和set容器(详解)
  • sscanf解析
  • 中专生实习找什么工作?