java的JWT介绍
什么是 JWT
JWT(JSON Web Token)是一种用于在网络应用之间安全传输信息的开放标准(RFC 7519)。它通常由三部分组成,以紧凑的形式表示,能够在不同的服务或系统之间安全地传递声明(claims)。简单来说,JWT 就像是一张“通行证”,包含了一些必要的信息,并且经过加密处理,接收方可以验证这张“通行证”的真实性和完整性。
JWT 的结构
JWT 由三部分组成,各部分之间用点(.)分隔,格式为 Header.Payload.Signature。
1. Header(头部)
Header 通常由两部分组成:令牌的类型(通常是 JWT)和使用的签名算法,如 HMAC SHA256 或 RSA。它是一个 JSON 对象,然后进行 Base64Url 编码。
示例:
{
"alg": "HS256",
"typ": "JWT"
}
编码后可能是这样:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
2. Payload(负载)
Payload 包含声明(claims),声明是关于实体(通常是用户)和其他数据的声明。声明分为三种类型:
- 注册声明:如
iss(发行人)、sub(主题)、aud(受众)等,这些是 JWT 标准中预定义的声明。 - 公开声明:由各方自由定义。
- 私有声明:在同意使用的各方之间定义的声明。
示例:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
编码后可能是:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
3. Signature(签名)
要创建签名部分,需要使用编码后的 Header、编码后的 Payload、一个秘钥(secret)和 Header 中指定的签名算法。例如,使用 HMAC SHA256 算法,签名将按以下方式创建:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名用于验证消息在传输过程中没有被更改,并且在使用私钥签名的情况下,还可以验证 JWT 的发送者的身份。
JWT 的工作流程
- 用户登录:用户向服务器发送登录请求,提供用户名和密码。
- 服务器验证:服务器验证用户的凭据,如果验证通过,服务器会创建一个 JWT,并将其返回给客户端。
- 客户端存储:客户端接收到 JWT 后,通常会将其存储在本地(如 localStorage 或 cookie)。
- 后续请求:在后续的请求中,客户端会将 JWT 包含在请求头(如
Authorization: Bearer <JWT>)中发送给服务器。 - 服务器验证:服务器接收到请求后,会验证 JWT 的签名和有效性。如果验证通过,服务器会处理请求并返回响应。
示例代码
以下是一个使用 Java 和 jjwt 库生成和验证 JWT 的示例:
添加依赖
如果你使用 Maven,可以在 pom.xml 中添加以下依赖:
<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>
生成 JWT
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtGenerator {
private static final String SECRET_KEY = "yourSecretKey";
public static String generateToken(String subject) {
return Jwts.builder()
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24)) // 过期时间为 24 小时
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
验证 JWT
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
public class JwtValidator {
private static final String SECRET_KEY = "yourSecretKey";
public static Claims validateToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
测试代码
public class Main {
public static void main(String[] args) {
// 生成 JWT
String token = JwtGenerator.generateToken("123456");
System.out.println("Generated JWT: " + token);
// 验证 JWT
try {
Claims claims = JwtValidator.validateToken(token);
System.out.println("Subject: " + claims.getSubject());
} catch (Exception e) {
System.out.println("Invalid JWT: " + e.getMessage());
}
}
}
代码解释
JwtGenerator.generateToken方法:使用Jwts.builder()创建一个 JWT 构建器,设置主题、签发时间、过期时间,并使用 HMAC SHA256 算法和秘钥进行签名,最后调用compact()方法生成 JWT。JwtValidator.validateToken方法:使用Jwts.parser()创建一个 JWT 解析器,设置签名秘钥,调用parseClaimsJws(token)方法解析 JWT,如果验证通过,返回 JWT 的负载部分(Claims)。
通过这种方式,你可以在 Java 中方便地生成和验证 JWT,实现安全的信息传输。
Java的JWT目前有以下常见应用场景及成熟案例:
应用场景
- 单点登录(SSO):在多个相关但独立的系统中,用户只需登录一次,就能访问其他相互信任的系统,无需再次输入用户名和密码。JWT可以在用户登录主系统后生成,然后用户访问其他子系统时,携带该JWT进行身份验证,实现单点登录的效果。
- 前后端分离项目:在前后端分离架构中,前端和后端是独立开发、部署的。前端通过调用后端提供的API获取数据和执行操作。用户登录后,后端生成JWT返回给前端,前端在后续的请求中,将JWT放在请求头中发送给后端,后端通过验证JWT来确定用户身份和权限,从而返回相应的数据和处理结果。
- 微服务架构:在微服务架构中,通常包含多个相互独立的微服务。当用户请求涉及多个微服务时,JWT可以在各个微服务之间传递,用于验证用户身份和传递用户相关信息,确保各个微服务能够安全、准确地处理请求。
- 移动应用与后端交互:移动应用与后端服务器进行通信时,也常使用JWT进行身份验证和授权。用户在移动应用中登录后,后端为其生成JWT,移动应用将JWT存储在本地,后续请求都携带JWT,以便后端识别用户身份,提供相应的服务。
成熟案例
- Spring Cloud微服务项目:许多采用Spring Cloud构建的微服务项目会使用JWT进行身份认证和授权管理。例如,在一个大型电商微服务系统中,包括用户服务、订单服务、商品服务等多个微服务。用户登录后,系统会生成JWT,该JWT会在用户与各个微服务之间的交互中传递,用于验证用户身份和判断用户是否具有访问相应资源的权限。
- 大型企业OA系统:一些大型企业的办公自动化(OA)系统采用前后端分离架构,使用JWT实现用户身份认证。员工通过Web端或移动端登录OA系统后,系统会为其生成JWT。员工在进行请假、审批、查看文档等操作时,前端会将JWT携带在请求中发送给后端,后端根据JWT中的信息进行权限验证和业务处理。
- 开源项目Shiro:Apache Shiro是一个强大且易用的Java安全框架,它支持JWT等多种身份验证方式。在很多基于Shiro框架的项目中,开发人员会利用Shiro对JWT的支持,实现安全的身份认证和授权功能。例如,一些小型的Web应用项目,使用Shiro结合JWT来保护应用的资源,确保只有合法用户能够访问相应的功能和数据。

浙公网安备 33010602011771号