文章目录
- 什么是JWT?
- JWD对字符串进行Base64加密
- JWT加密字符串解释
- JWT使用场景
- jwt 特点
- JWT token在线解密
什么是JWT?
JWT(json web token),它并不是一个具体的技术实现,而更像是一种标准。
JWT规定了数据传输的结构,一串完整的JWT由三段落组成,每个段落用英文句号连接(.)连接,他们分别是:Header、Payload、Signature,所以,常规的JWT内容格式是这样的:AAA.BBB.CCC
并且,这一串内容会base64加密;也就是说base64解码就可以看到实际传输的内容。接下来解释一下这些内容都有什么作用。
简单理解:jwt本质就是, 把用户信息通过加密后生成的一个字符串
JWD对字符串进行Base64加密
- pom文件引用jwt的jar包
<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
- 对字符串进行加密
static String secrest = "fdgfdfgds";
public static void main(String[] args) {
String str = "小明";
String compact = Jwts.builder().setSubject(str).signWith(SignatureAlgorithm.HS256, secrest).compact();
System.out.println(compact);
}
结果:
3. 对加密过的字符串进行解密,得到解密前的原文
static String secrest = "fdgfdfgds";
public static void main(String[] args) {
String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiLlsI_mmI4ifQ.FUasyP5RAr94XPzPp21cMgvM-z2ka1nRCmjPydNLBy8";
Claims body = Jwts.parser().setSigningKey(secrest).parseClaimsJws(token).getBody();
String subject = body.getSubject();
System.out.println(subject);
}
结果:
4. 对加密字符串进行时间限制
static String secrest = "fdgfdfgds";
public static void main(String[] args) throws InterruptedException {
String str = "小明";
String compact = Jwts.builder().setSubject(str).setExpiration(new Date(System.currentTimeMillis()+1000*5)).signWith(SignatureAlgorithm.HS256, secrest).compact();
System.out.println(compact);
Thread.sleep(3000);
Claims body = Jwts.parser().setSigningKey(secrest).parseClaimsJws(compact).getBody();
String subject = body.getSubject();
System.out.println(subject);
}
在token生成后五秒内进行解密,则能成功解密
如果超出时间限制,修改为六秒后解析,那么就会解析失败,提示超出时间限制
JWT加密字符串解释
eyJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiLlsI_mmI4ifQ.
FUasyP5RAr94XPzPp21cMgvM-z2ka1nRCmjPydNLBy8
jwt加密过后的字符串,根据小数点可以分为3串,Header,Payload,Signature
- Header :
JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。
- Payload
有效载荷部分,JWT主体内容部分,是一个包含需要传递数据的JSON对象。 其中有七个默认字段供选择。
{
"iss":发行人
"exp":到期时间
"sub":主题
"aud":用户
"nbf":在此之前不可用
"iat":发布时间
"jti":JWT ID用于标识该JWT
}
以上默认字段并不要求强制使用。我们还可以自定义私有字段,一般会把包含用户信息的非保密数据放到payload中。
{
"sub": "1234567890",
"name": "chongchong",
"admin": true
}
注意:默认情况下JWT是未加密的,只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息
- Signature
签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名
HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
JWT使用场景
简单理解:生成一个与用户名对应的加密字符串作为token。
使用场景:
- 在用户第一次登录成功的时候返回一个token,客户端收到token,带着token进行第二次请求,服务端验证该token是否存在,存在则进行业务逻辑的处理。问题就是如果生成token,那以后知道token后,随时都能请求,增加了不安全性。
- 在使用token的时候加入时间机制,比如在token生成后30分后失效,那在三十分钟之内请求,需要给token重新赋予时间30分后失效。如果遇到分布式怎么办呢。
- 可以加入redis缓存,为每个token赋予时间限制,在请求另外服务的时候,可以去redis中查询是否存在这个token,存在放行,不存在重新登录。
jwt 特点
1、JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权
限,一旦JWT签发,在有效期内将会一直有效。
2、JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。
3、为了减少盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS协议进行传输。期间不可能取消令牌或更改令牌的权限,一旦JWT签发,在有效期内将会一直有效。
JWT token在线解密
token在线解密