jwt
简介链接:https://www.bilibili.com/video/BV1cK4y197EM?spm_id_from=333.337.search-card.all.click
具体文章:https://www.baobao555.tech/posts/4cc42459/
什么是jwt
JSON Web Token,通过数字签名的方式,以JSON对象为载体,在不同的服务终端之间安全的传输信息。
应用场景
JWT最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含JWT,系统在每次处理用户请求的之前,都要先进行JWT安全校验,通过之后再进行处理。
jwt的组成
由三部分组成,用. 拼接
JWTString = Base64(Header).
Base64(Payload).
HMACSHA256(
(
base64UrlEncode(header) + “.”
+ base64UrlEncode(payload)
), secret
)
这三部分分别是:
{
'typ': 'JWT'
'alg': 'HS256'
}
通过base64编码,形成第一部分
{
"name": 'czc'
}
通过base64编码,形成第二部分
- Signature (签名)
把header和payload部分的先通过base64编码并连接,再通过header中的加密方式把刚刚得到的字符串再次加密,形成第三部分
var encodedstring = base64Ur1Encode(header) +
'.’ + base64ur1Encode(pay1oad);
var signature = HMACSHA256(encodedstring,'secret');
依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.1</version>
</dependency>
加密解密(对称签名)
加密
Map<String, Object> header = new HashMap<>();
header.put("typ", "JWT");
header.put("alg", "HS256");
String jwtToken = JWT.create()
.withHeader(header)
.withClaim("username", "czc")
.withClaim("password", 1244)
.withSubject("测试")
.withExpiresAt(new Date(System.currentTimeMillis() + overTime))
.sign(Algorithm.HMAC256("czc"));
System.out.println(jwtToken);
解密:
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiLmtYvor5UiLCJwYXNzd29yZCI6MTI0NCwiZXhwIjoxNjUwMTg0MDQzLCJ1c2VybmFtZSI6ImN6YyJ9.Uifc9hO3Givnp0iYPSXhTdsNNjo_L8NSNVBZXA87NNQ";
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("czc")).build();
DecodedJWT decodedJWT = jwtVerifier.verify(token);
Claim password = decodedJWT.getClaim("password");
Claim userName = decodedJWT.getClaim("username");
System.out.println(password.asInt());
System.out.println(userName.asString());
System.out.println(decodedJWT.getExpiresAt());
System.out.println(decodedJWT.getSignature());
System.out.println(decodedJWT.getHeader());
整合springboot
在实际的SpringBoot项目中,一般我们可以用如下流程做登录:
- 在登录验证通过后,给用户生成一个对应的随机token(注意这个token不是指jwt,可以用uuid等算法生成),然后将这个token作为key的一部分,用户信息作为value存入Redis,并设置过期时间,这个过期时间就是登录失效的时间
- 将第1步中生成的随机token作为JWT的payload,生成JWT字符串返回给前端
- 前端之后每次请求都在请求头中的Authorization字段中携带JWT字符串
- 后端定义一个拦截器,每次收到前端请求时,都先从请求头中的Authorization字段中取出JWT字符串并进行验证,验证通过后解析出payload中的随机token,然后再用这个随机token得到key,从Redis中获取用户信息,如果能获取到就说明用户已经登录
|