一、jwt学习
公式
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),)
jwt官网:https://jwt.io/
json优点:可读性高,占带宽小,轻量级
base64不属于算法,属于编码
TOKEN代替session
springsecurity
JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:
- Header
- Payload
- Signature
一个典型的JWT看起来是这个样子的:
xxxxx.yyyyy.zzzzz
第一部分
- Header header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。
'alg' "HS256"
'typ' "JWT"
然后,用Base64对这个JSON编码就得到JWT的第一部分
第二部分
- Payload JWT的第二部分是payload,它包含声明(要求)。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型: registered, public 和 private。
- Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
- Public claims : 可以随意定义。
- Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。 下面是一个例子:
"sub" '1234567890'
"name" 'john'
"admin"
对payload进行Base64编码就得到JWT的第二部分
第三部分
注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的。
- Signature
为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。
二、手写jwt
//String SIGN_KEY = "123456";
@Test
void writeJwt() throws JSONException {
//手写jwt 分钟三部分参数 header、 payload、sign签名值
//header
JSONObject header = new JSONObject();
header.put("alg", "HS256");
//payload
JSONObject payload = new JSONObject();
payload.put("phone", "130****8260");
String headerEncoded = Base64.getEncoder().encodeToString(header.toString().getBytes());
String payLoadJsonStr = payload.toString();
String payLoadEncoded = Base64.getEncoder().encodeToString(payLoadJsonStr.getBytes());
// sign签名值 实际上就是md5
String sign = DigestUtils.md5Hex(payLoadJsonStr + SIGN_KEY);
String jwt = headerEncoded + "." + payLoadEncoded + "." + sign;
System.out.println(jwt);
}
三、jwt加密解密
// jwt加密与解密
String SIGN_KEY = "123456";
@Test
void getJwtTest(){
// =====加密
long now = System.currentTimeMillis();
//过期时间1分钟
long exp = now+1000 * 5;
JwtBuilder jwtBuilder = Jwts.builder().claim("userImg", "1234")
.signWith(SignatureAlgorithm.HS256, SIGN_KEY)
.setExpiration(new Date(exp));
System.out.println(jwtBuilder.compact());
// =====解密
try {
Thread.sleep(2000);
}catch (Exception e){
System.out.println(e.getMessage());
}
Claims body = Jwts.parser().setSigningKey(SIGN_KEY).parseClaimsJws(jwtBuilder.compact()).getBody();
System.out.println(body);
}