首先什么是JWT?
JWT的全称是json web token,是在json风格轻量级的授权和身份认证规范,可实现无状态、分布式的web应用授权
JWT由三部分组成
- jwtHeader:通常有俩部分组成
- 声明类型(type),默认为“jwt”
- 加密类型,自定义
- 载荷数据,指有效数据,一般如下:
- 用户身份信息(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息)
- 注册声明:如token的签发时间,过期时间,签发人等
- 签名:是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性
JWT的Demo
eyJhbGciOiJIUzI1NiJ9 //jwt头
.eyJqdGkiOiIxIiwic3ViIjoieXFxIiwiaWF0IjoxNTY4Nzc0NzM1LCJwZXJtcyI6IjExMTExIiwiZXhwIjoxNTY4Nzc0NzM1fQ //载荷数据
.cDJ5-L2GAbUSqSCWjqE-NEsXEaYQJr3loADiUCHF0XA //签名
JWT的交互过程
1.首先用户执行登录操作,传递用户名与密码给服务端
2.服务端验证身份信息后,根据密码生成token,并返回给客户端浏览器
3.客户端后续请求均携带token
4.服务端接收到请求后根据密钥解析token中签名是否有效,若有效,则取出载荷数据
5.处理请求,返回响应结果
使用的maven依赖
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
测试Demo如下:
package com.bdcloud.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Getter
@Setter
@NoArgsConstructor
@ConfigurationProperties("jwt.config")
public class JwtUtils {
//签名私钥
private String key;
//签名的失效时间
private Long ttl;
public JwtUtils(String key,Long ttl){
this.key = key;
this.ttl = ttl;
}
/**
* 设置认证token
* id:登录用户id
* subject:登录用户名
*
*/
public String createJwt(String id, String name, Map<String,Object> map) {
//1.设置失效时间
long now = System.currentTimeMillis();//当前毫秒
long exp = now + ttl;
//2.创建jwtBuilder
JwtBuilder jwtBuilder = Jwts.builder().setId(id)
.setSubject(name) //设置主题
.setIssuedAt(new Date())//生成签名的时间
.signWith(SignatureAlgorithm.HS256, key);
//3.根据map设置claims-即载荷信息
// for(Map.Entry<String,Object> entry : map.entrySet()) {
// jwtBuilder.claim(entry.getKey(),entry.getValue());
// }
jwtBuilder.addClaims(map);
jwtBuilder.setExpiration(new Date(exp)); //设置过期时间
//4.创建token
String token = jwtBuilder.compact();
return token;
}
/**
* 解析token字符串获取clamis
*/
public Claims parseJwt(String token) {
Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
return claims;
}
public static void main(String[] args) {
JwtUtils jwtUtils = new JwtUtils();
jwtUtils.setKey("lixiangfeng");
jwtUtils.setTtl(1000l);
// Map<String,Object> map = new HashMap<>();
// map.put("perms","11111");
// String yqq = jwtUtils.createJwt("1","yqq", map);
// System.out.println(yqq);
//eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoieXFxIiwiaWF0IjoxNTY4Nzc0NzM1LCJwZXJtcyI6IjExMTExIiwiZXhwIjoxNTY4Nzc0NzM1fQ.cDJ5-L2GAbUSqSCWjqE-NEsXEaYQJr3loADiUCHF0XA
//eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoieXFxIiwiaWF0IjoxNTY4Nzc0ODA5LCJwZXJtcyI6IjExMTExIiwiZXhwIjoxNTY4Nzc0ODEwfQ.6-TEst7LqFvC3ADBtE5TlwHUarSU5lpehZ-iSZ2WsK4
Claims claims = jwtUtils.parseJwt("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoieXFxIiwiaWF0IjoxNTY4Nzc0NzM1LCJwZXJtcyI6IjExMTExIiwiZXhwIjoxNTY4Nzc0NzM1fQ.cDJ5-L2GAbUSqSCWjqE-NEsXEaYQJr3loADiUCHF0XA");
String perms = (String) claims.get("perms");
System.out.println(perms);
}
}