basic auth : 每次请求都会携带用户的username,password,易被黑客拦截。
Cookie auth : 我们请求服务器,创建一个session对象,客户端创建cookie对象。客户端每次访问,携带cookie对象。
(在当今,前后端分离中,通过前端服务器代理或反向代理,进行请求转发,从将cookie储存在客户端。)
oauth2 auth : 可以第三方登录,但是比较麻烦下去授权服务器获取授权码,再拿到token,再去访问资源服务。
token auth : 一般用户注册登录之后,生成token对象分别存储在数据库,以及客户端的localStore 或者 Cookie中。
jwt 全称 JSON Web Token ,简单来讲是一个拥有json格式的Token。
简单的理解:一种token的实现方式。
{
"alg" : "HS256",
"type" : "JWT"
}
{
"sub" : "123",
"name" : "John Do",
"admin" : true
}
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret);
1.jwt对比与传统json和session不需要在服务端存储
2.负载中包含了用户所需要的信息,避免多次查询数据库
我们这里采用的jjwt实现。并且基于springboot项目实现的。
io.jsonwebtoken
jjwt
0.9.1
这将信息加密成jwt。
JwtBuilder jwtBuilder = Jwts.builder()
// 声明的标识{"jti":"8888"} 唯一的
.setId("8888")
// 主体,用户{"sub":"Rose"}
.setSubject("Rose")
// 创建日期 {"iat":"" }
.setIssuedAt(new Date())
// 用的什么编码
.signWith(SignatureAlgorithm.HS256,"12345");
// 拿到token
String token = jwtBuilder.compact();
System.out.println(token);
System.out.println("---------------------");
String[] split = token.split("\\.");
System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
// 无法解密
System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
这个token需要自己替换成你生成的token。
String token = "eyJhbGciOiJIUzI1NiJ9." +
"eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY4NzIyODc0MX0." +
"TiMu_sWRQxmlUtY-xh9G4G26UXYwGxID0kj6XC-iblI";
// 解析token获取负载中声明的对象
Claims claims = Jwts.parser()
// 这里的签名秘钥
.setSigningKey("12345")
.parseClaimsJws(token)
.getBody();
System.out.println("id:"+claims.getId());
System.out.println("subject:"+claims.getSubject());
System.out.println("issuedAt:"+claims.getIssuedAt());
衔接上述生成和解析token代码。
我们在jwt代码中新加入,
long now = new Date().getTime(); // ---新增
long exp = now + 60 * 1000; // 设置60s后过期 // ---新增
JwtBuilder jwtBuilder = Jwts.builder()
// 声明的标识{"jti":"8888"} 唯一的
.setId("8888")
// 主体,用户{"sub":"Rose"}
.setSubject("Rose")
// 发行日期 {"iat":"" }
.setIssuedAt(new Date())
// 用的什么编码, secret 这是解密的秘钥(!)
.signWith(SignatureAlgorithm.HS256,"12345")
// 设置token过期时间
.setExpiration(new Date(exp)); // --- 新增
我们在解析token中,新加用来验证token过期时间,和生成时间。
PS:simpleDateFormat.format() 方法,内部没有校验null的逻辑,因此必须先生成jwt时,设置过期时间,否则为null,报异常。
System.out.println("----------------------");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("jwt生成日期:"+simpleDateFormat.format(claims.getIssuedAt()));
System.out.println("jwt过期日期:"+simpleDateFormat.format(claims.getExpiration()));
System.out.println("当前日期:"+simpleDateFormat.format(new Date()));
我们可以在jwt中自定义claims,(这些信息会存入负载中)
衔接,上文。
JwtBuilder jwtBuilder = Jwts.builder()
// 声明的标识{"jti":"8888"} 唯一的
.setId("8888")
// 主体,用户{"sub":"Rose"}
.setSubject("Rose")
// 发行日期 {"iat":"" }
.setIssuedAt(new Date())
// 用的什么编码去签名,12345 明文秘钥(secret)
.signWith(SignatureAlgorithm.HS256,"12345")
// 设置token过期时间
.claim("role","admin"); // --- 新增
// 直接传入map对象
//.addClaims(new HashMap<>())
同样,我们也可以在解析token中获得到他。
System.out.println(claims.get("role"));