什么是 JWT?
JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。 从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。
JWT 由哪些部分组成?
JWT 本质上就是一组字串,通过(.
)切分成三个为 Base64 编码的部分:
- Header : 描述 JWT 的元数据,定义了生成签名的算法以及
Token
的类型。 - Payload : 用来存放实际需要传递的数据
- Signature(签名) :服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。
JWT 通常是这样的:xxxxx.yyyyy.zzzzz
Header
Header 通常由两部分组成:
typ
(Type):令牌类型,也就是 JWT。alg
(Algorithm) :签名算法,比如 HS256。
{
"alg": "HS256",
"typ": "JWT"
}
Payload
Payload 也是 JSON 格式数据,其中包含了 Claims(声明,包含 JWT 的相关信息)。
Claims 分为三种类型:
- Registered Claims(注册声明) :预定义的一些声明,建议使用,但不是强制性的。
- Public Claims(公有声明) :JWT 签发方可以自定义的声明,但是为了避免冲突,应该在 IANA JSON Web Token Registryopen in new window 中定义它们。
- Private Claims(私有声明) :JWT 签发方因为项目需要而自定义的声明,更符合实际项目场景使用。
下面是一些常见的注册声明:
iss
(issuer):JWT 签发方。iat
(issued at time):JWT 签发时间。sub
(subject):JWT 主题。aud
(audience):JWT 接收方。exp
(expiration time):JWT 的过期时间。nbf
(not before time):JWT 生效时间,早于该定义的时间的 JWT 不能被接受处理。jti
(JWT ID):JWT 唯一标识。
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature
Signature 部分是对前两部分的签名,作用是防止 JWT(主要是 payload) 被篡改。
这个签名的生成需要用到:
- Header + Payload。
- 存放在服务端的密钥(一定不要泄露出去)。
- 签名算法。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
) secret base64 encoded
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.
)分隔,这个字符串就是 JWT 。
简单加密解密实现
private long time=1000*60*60*24;
private String signature="admin";
@Test
public void jwt(){
JwtBuilder jwtBuilder= Jwts.builder();
String jwtToken=jwtBuilder
//header
.setHeaderParam("typ","JWT")
.setHeaderParam("alg","Hs256")
//payload
.claim("username","Tom")
.claim("role","admin")
.setSubject("admin-test")
.setExpiration(new Date(System.currentTimeMillis()+time))
.setId(UUID.randomUUID().toString())
//signature
.signWith(SignatureAlgorithm.HS256,signature)
//拼接
.compact();
}
@Test
public void parse(){
String token="xx.xxx.xx";
JwtParser jwtParser=Jwts.parser();
Jws<Claims> claimsJws = jwtParser.setSigningKey(signature).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
System.out.println(claims.get("username"));
System.out.println(claims.getId());
}
maven坐标
<!-- JWT -->
<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.1</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>
标签:JWT,Header,Token,签名,Claims,Payload
From: https://www.cnblogs.com/Muieay/p/17110501.html