十分钟入门JWT(JSON Web Token)

1、简介

JWT,JSON Web Token的简写,是目前比较流行的跨域认证解决方案,它不是一个具体的技术实现,而更像是一种标准。
官网:JSON Web Tokens - jwt.io

2、JWT数据结构

JWT由3部分构成:

  • Header(头部)
  • Payload(负载)
  • Signature(签名)

Header
Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

alg
属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);
typ
属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

最后,将上面的 JSON 对象使用 Base64URL 算法转成字符串。

Payload
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。如:

1
2
3
4
{
"id": "123",
"name": "river"
}

JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。

这个 JSON 对象也要使用 Base64URL 算法转成字符串。

Signature
Signature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用(.)分隔。

JWT是可以被解码的,所以不要在JWT的Payload中存放私密数据。

JWT

3、JWT使用

引入依赖

1
2
3
4
5
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>

由于我们需要通过jwt生成token,并能通过token解析生成原始数据,所以可以封装成工具类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.*;

public class JwtUtils {

private static final String SECRET = "jwt123456";

public static String generateToken(Map<String, Object> claims, Date expireTime) {
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS256, SECRET)
.setExpiration(expireTime)
.compact();
}

public static Map<String, Object> parseToken(String token) {
try {
Claims body = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
return body;
} catch (ExpiredJwtException e) {
e.printStackTrace();
}
return null;
}
}

在我们做登录鉴权的项目时,服务端生成jwt返回给客户端,客户端可以将jwt储存在Cookie里面,也可以储存在 localStorage。此后,客户端每次与服务器通信,都带上这个jwt。放在 Cookie 里面可以自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求头中。

4、使用JWT需要注意的地方

1、JWT 中的数据默认是不加密的,不加密的情况下,不能将秘密数据写入JWT;
2、一旦JWT签发了,在到期之前始终有效,除非服务器有额外的限制逻辑(如使用redis控制登录session有效期),所以需要设置有效期;
3、为防止泄露,JWT不应该使用HTTP协议明码传输,要使用HTTPS协议传输。

参考:
JSON Web Token 入门教程 - 阮一峰的网络日志


十分钟入门JWT(JSON Web Token)
https://river106.cn/posts/b12ba8d4.html
作者
river106
发布于
2021年12月25日
许可协议