JWT快速入门
简介
JWT:JSON Web Token,是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
作用:JWT最常见的场景的授权认证,一旦用户登录之后,后续每个请求都会包含JWT,系统处理每次用户请求之前,都会先进行JWT安全校验,通过之后再进行处理。
组成:JSON Web Token
由三部分组成,它们之间用圆点(.)连接。这三部分分别是:
- Header(首标)
{
'alg': "HS256", # 使用的算法
'typ': "JWT"
}
- Payload(负载)
{
"sub": '1234567890',
"name": 'john',
"admin":true
}
- Signature(签名)
// 首先是使用base64UrlEncode方法把header与payload拼接起来
var encodedstring = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
// 然后在使用算法对上面拼接的字符串进行加密 使用的算法就是上面header中的那个alg
var signature = HMACSHA256(encodedString, 'secret');
代码展示
创建一个Java项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>JWT</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</project>
测试代码
- 加密过程
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.UUID;
public class Test {
// 持续的时间
private long time = 1000 * 60 * 60 * 24; // 一天的毫秒数
// 数字签名
private String signature = "admin";
@org.junit.Test
public void jwtTest(){
JwtBuilder jwtBuilder = Jwts.builder();
// 采用链式编程传参
String jwtToken = jwtBuilder
// header->设置类型
.setHeaderParam("typ","JWT")
// header->这是算法
.setHeaderParam("alg","HS256")
// payload 设置用户情况
.claim("username", "lihua")
.claim("role", "admain")
// 设置主题
.setSubject("admin-test")
// 设置持续的有效时间
.setExpiration(new Date(System.currentTimeMillis() + time))
// 设置随机id
.setId(UUID.randomUUID().toString())
// signature 设置数字签名加密
.signWith(SignatureAlgorithm.HS256, signature)
// 将这几部分拼接起来
.compact();
// 打印结果
System.out.println(jwtToken);
}
}
运行结果
结果由三部分构成
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJ1c2VybmFtZSI6ImxpaHVhIiwicm9sZSI6ImFkbWFpbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NzE3NzkzOTMsImp0aSI6IjA5M2Y2NWYwLTg2M2YtNDAzZS1iMjQzLTlkNTY0NmQzZThhMCJ9
.8uN_E9Dd5HxEd43A4GUi12pMKNEQ95_6LerPnoiWuCY
- 解密过程
@org.junit.Test
public void parse(){
// 密文
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImxpaHVhIiwicm9sZSI6ImFkbWFpbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NzE3NzkzOTMsImp0aSI6IjA5M2Y2NWYwLTg2M2YtNDAzZS1iMjQzLTlkNTY0NmQzZThhMCJ9.8uN_E9Dd5HxEd43A4GUi12pMKNEQ95_6LerPnoiWuCY";
JwtParser jwtParser = Jwts.parser();
// 使用数字签名解密
Jws<Claims> claimsJws = jwtParser.setSigningKey(signature).parseClaimsJws(token);
// 获取存储体payload
Claims claims = claimsJws.getBody();
// 输出加密结果
System.out.println(claims.get("username"));
System.out.println(claims.get("role"));
System.out.println(claims.getId());
System.out.println(claims.getSubject());
System.out.println(claims.getExpiration());
}
运行结果
完整代码
import io.jsonwebtoken.*;
import java.util.Date;
import java.util.UUID;
public class Test {
// 持续的时间
private long time = 1000 * 60 * 60 * 24; // 一天的毫秒数
// 数字签名
private String signature = "admin";
@org.junit.Test
public void jwtTest(){
JwtBuilder jwtBuilder = Jwts.builder();
// 采用链式编程传参
String jwtToken = jwtBuilder
// header->设置类型
.setHeaderParam("typ","JWT")
// header->这是算法
.setHeaderParam("alg","HS256")
// payload 设置用户情况
.claim("username", "lihua")
.claim("role", "admain")
// 设置主题
.setSubject("admin-test")
// 设置持续的有效时间
.setExpiration(new Date(System.currentTimeMillis() + time))
// 设置随机id
.setId(UUID.randomUUID().toString())
// signature 设置数字签名加密
.signWith(SignatureAlgorithm.HS256, signature)
// 将这几部分拼接起来
.compact();
// 打印结果
System.out.println(jwtToken);
}
@org.junit.Test
public void parse(){
// 密文
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImxpaHVhIiwicm9sZSI6ImFkbWFpbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NzE3NzkzOTMsImp0aSI6IjA5M2Y2NWYwLTg2M2YtNDAzZS1iMjQzLTlkNTY0NmQzZThhMCJ9.8uN_E9Dd5HxEd43A4GUi12pMKNEQ95_6LerPnoiWuCY";
JwtParser jwtParser = Jwts.parser();
// 使用数字签名解密
Jws<Claims> claimsJws = jwtParser.setSigningKey(signature).parseClaimsJws(token);
// 获取存储体payload
Claims claims = claimsJws.getBody();
// 输出加密结果
System.out.println(claims.get("username"));
System.out.println(claims.get("role"));
System.out.println(claims.getId());
System.out.println(claims.getSubject());
System.out.println(claims.getExpiration());
}
}