JWT的基础与使用

JWT JSON Web Token 是一种用于在各方之间传输信息的紧凑、安全的方式,常用于身份验证和授权。它以令牌的形式将用户信息编码后传输,可以确保数据的完整性和安全性。

1.JWT的结构

JWT 是一个基于 JSON 的令牌,由三部分组成,通过点号 (.) 分隔:

header.payload.signature

每部分都是经过 Base64Url 编码的字符串,分别对应以下三个部分:

1)Header (头部)

头部包含令牌的元数据,通常包括令牌类型和签名算法。

例子:

|--------------------------------------------------|
| { "alg": "HS256", "typ": "JWT" } |

alg: 签名使用的算法(如 HMAC SHA256)。

typ: 声明令牌类型为 JWT。

2)Payload (有效载荷)

有效载荷包含用户的声明(claims),也就是实际传输的数据。它通常包含身份验证或授权所需的信息。

|-------------------------------------------------------------------------------------------------------|
| { "sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022 } |

常见的标准声明:

  • iss (issuer):签发者
  • sub (subject):面向的用户
  • aud (audience):接收的受众
  • exp (expiration):过期时间
  • iat (issued at):签发时间
  • nbf (not before):生效时间

自定义声明:可以根据需求添加任何信息。

3)Signature (签名)

签名用于验证令牌的真实性,并确保令牌在传输过程中没有被篡改。

签名的生成方式:

|--------------------------------------------------------------------------------|
| HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret ) |

签名使用头部中声明的算法和一个秘密密钥(secret key)生成。

2.JWT的工作流程

2.1.生成JWT

用户登录后,服务器生成一个包含用户身份信息的 JWT,使用密钥对其进行签名。

2.2.客户端存储JWT

生成的 JWT 会返回给客户端,客户端通常将其存储在浏览器的 localStoragesessionStorage 中,或者存储在 Cookie 中。

2.3.客户端请求时携带JWT

在后续的请求中,客户端将 JWT 附加在请求头的 Authorization 字段中:

|---------------------------------|
| Authorization: Bearer <token> |

2.4.服务器验证JWT

服务器接收到 JWT 后,会使用相同的密钥对签名进行验证,确保令牌的完整性和真实性。

如果 JWT 有效,服务器允许访问资源;如果令牌无效或过期,返回 401 未授权状态。

3.JWT的优势

1)无状态:JWT 是无状态的,所有信息都保存在令牌中,服务器不需要维护会话数据。

2)跨域支持:由于 JWT 不依赖于特定的存储机制,适合跨域认证。

3)紧凑性:JWT 的结构紧凑,便于在 URL、HTTP 请求头等地方传输。

4)灵活性:JWT 可以包含任意声明,支持灵活的身份和权限管理。

4.JWT的使用场景

1)身份认证:用户登录后生成 JWT,之后每次请求时验证 JWT 以实现认证。

2)授权:通过 JWT 传递用户权限信息,确保用户只能访问被授权的资源。

3)信息传递:JWT 可以安全地传输一些加密的信息。

5. JWT 的安全性注意事项

签名算法 :建议使用强大的签名算法(如 HS256RS256),避免使用不安全的算法。

HTTPS:JWT 中可能包含敏感信息,传输时必须使用 HTTPS 来防止令牌被截获。

令牌过期 :为 JWT 设置合理的过期时间(exp 声明),防止长期有效的令牌被滥用。

刷新令牌:使用短期有效的访问令牌和长期有效的刷新令牌(Refresh Token)机制,以便在访问令牌过期后请求新的令牌。

6.Java代码实现生成和验证JWT

6.1.添加Maven依赖

如果你使用 Maven 构建项目,首先在 pom.xml 中添加 JJWT 库的依赖:

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

6.2.生成和验证 JWT 的 Java 代码

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| package com.me.mengyu.auth.net.jwt; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.Claims; import io.jsonwebtoken.security.Keys; import javax.crypto.SecretKey; import java.util.Date; public class JwtExample { // 生成一个密钥,用于签名 private static final SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256 ); // 创建 JWT public static String createJwt(String subject) { // 设置 JWT 过期时间 long expirationTime = 1000 * 60 * 60; // 1 小时 return Jwts.builder() .setSubject(subject) // 设置主题(可以是用户ID等信息) .setIssuer("your-app") // 设置发行者 .setIssuedAt(new Date()) // 设置签发时间 .setExpiration(new Date(System.currentTimeMillis() + expirationTime)) // 设置过期时间 .signWith(SECRET_KEY ) // 使用密钥签名 .compact(); // 生成 JWT } // 验证 JWT 并提取信息 public static void validateJwt(String token) { try { // 解析 JWT Claims claims = Jwts.parserBuilder() .setSigningKey(SECRET_KEY ) // 设置密钥 .build() .parseClaimsJws(token) // 验证令牌 .getBody(); // 输出从 JWT 中提取的信息 System.out .println("Subject: " + claims.getSubject()); System.out .println("Issuer: " + claims.getIssuer()); System.out .println("Expiration: " + claims.getExpiration()); } catch (Exception e) { System.out .println("Invalid JWT token: " + e.getMessage()); } } public static void main(String[] args) { // 创建 JWT String jwt = createJwt("1234567890"); // 这里的主题可以是用户的ID System.out .println("Generated JWT: " + jwt); // 验证 JWT validateJwt(jwt); } } |

代码说明:

1)createJwt****方法 :生成一个带有签名的 JWT,包含用户身份信息(subject),签发者(issuer),签发时间和过期时间。使用 HS256 算法和一个密钥签名。

  1. validateJwt****方法 :验证 JWT 是否有效,并从中提取 claims 信息(如 subjectissuerexpiration)。如果令牌无效(例如过期或签名不匹配),会抛出异常。

运行结果示例:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Generated JWT: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaXNzIjoieW91ci1hcHAiLCJpYXQiOjE3MjcwMTcyNDYsImV4cCI6MTcyNzAyMDg0Nn0.tNylO-O5Jbazd0QzR85X8OB7p1mDy0IGtyl97Ro0FYQ Subject: 1234567890 Issuer: your-app Expiration: Mon Sep 23 00:00:46 CST 2024 |

说明:

生成的 JWT :格式为 header.payload.signature,其中 payload 包含 sub(用户ID)、iss(发行者)等信息。

验证 :输出 SubjectIssuerExpiration,表明 JWT 验证成功并解析出了信息。

6.3.注意事项

1)密钥管理:在生产环境中,应该安全地管理密钥,避免泄露。

2)过期时间:务必设置合理的过期时间,防止长时间有效的令牌带来安全风险。

3)异常处理:应当详细处理验证失败的情况,比如过期令牌、签名错误等。

相关推荐
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
智驱力人工智能7 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
盟接之桥7 小时前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
数据与后端架构提升之路8 小时前
论系统安全架构设计及其应用(基于AI大模型项目)
人工智能·安全·系统安全
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端