=============
后端_网络令牌
=============
1 什么是JWT?
JWT可以生成一个加密的令牌,在用户成功登录后,发放给客户端。
客户端访问受限接口时,必须携带令牌,后端在验证令牌合法后,才接受访问。
JWT包括三个组成部分:
- 头部:固定内容{"typ":"JWT","alg":"HS256"}的Base64编码串。
{"typ":"JWT","alg":"HS256"}
|Base64
v
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
- 载荷:包含用户标识、过期时间等非敏感信息的Json字符串的Base64编码串。
{"sub":"1234567890","name":"John Doe","admin":true}
|Base64
v
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
- 签名:根据头部所示摘要算法做不同处理。
对于MD5摘要,计算“头部.载荷”加“盐”的摘要,获得其Base64编码串。
其它摘要,计算“头部.载荷”的摘要,用密钥加密后获得密文的Base64编码串。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
|加盐并计算摘要
|计算摘要并加密
|Base64
v
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
将以上三个编码串以“.”作为分隔符,拼接在一起,即得到专属于该用户的令牌。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
\__________________________________/ \__________________________________________________________________/ \_________________________________________/
| | |
头部 载荷 签名
2 添加依赖
/pom.xml:
...
io.jsonwebtoken
jjwt
0.9.1
...
/ysdblog-api/pom.xml:
...
io.jsonwebtoken
jjwt
...
3 添加工具类
/ysdblog-api/src/main/java/com/weihome/ysdblog/utils/JWTUtils.java:
public class JWTUtils {
private static final String secret = "123456Ysdblog!@###$$"; // 密钥
/**
* 生成令牌
*/
public static String createToken(Long userId){
Map claims = new HashMap<>(); // 自定义载荷
claims.put("userId", userId);
JwtBuilder jwtBuilder = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, secret) // 算法和密钥
.setClaims(claims) // 载荷中的自定义数据
.setIssuedAt(new Date()) // 签发时间
.setExpiration(new Date(System.currentTimeMillis() +
24 * 60 * 60 * 60 * 1000));// 有效期毫秒数(1天)
return jwtBuilder.compact();
}
/**
* 校验令牌
*/
public static Map checkToken(String token){
try {
Jwt parse = Jwts.parser().setSigningKey(secret).parse(token);
return (Map) parse.getBody(); // 返回载荷
}
catch (Exception e) { // 校验失败
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String token = JWTUtils.createToken(100L);
System.out.println(token);
Map payload = JWTUtils.checkToken(token);
System.out.println(payload);
}
}
4 运行测试
执行JWTUtils类的main()方法:
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NDk1MTUxMDYsInVzZXJJZCI6MTAwLCJpYXQiOjE2NDg2MjYwNzN9.n6AE7rK2coNi05FO2suqYrKn3xvA4a9Mib-voW2pklM
{exp=1649515106, userId=100, iat=1648626073}
\____________/ \________/ \____________/
| | |
到期时间 自定义载荷 签发时间