零、基本介绍
jwt是一种令牌,生成需要一个密钥,经过加密算法,得到一个token
格式:header.playload.signature
样例:eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJoaXNlbiIsImlhdCI6MTUxMjYyODUzNiwibmJmIjoxNTEyNjI4NTQ2LCJleHAiOjE1MTI2MjkxMzYsImhpc2VuSyI6Imhpc2VuViJ9.JKxvvYQyIJEN8Eg_6gN5NlnDokqVNApSd7eg3QGpjBfBARzx4ip4WRzSa0Ul2ScpdierKi9WxF1iTUdoHNRiaA
如果前端传给后台被修改的数据或者过期的数据,是无法校验通过的
签到拿到token之后,是可以经过base64解密,拿到 header.playload里面的信息(详情见第五步:解析token)
一、引入的包
<!--JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
二、jwt生成
public static final String key = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545df>?N<:{LWPW_hisen";
String jwt = Jwts.builder()
// JWT 所面向的用户
.setSubject("hisen")
// 设置密钥和加密算法
.signWith(SignatureAlgorithm.HS512, key)
// 设置签发时间
.setIssuedAt(new DateTime().toDate())
// 设置生效时间
.setNotBefore(new DateTime(System.currentTimeMillis() + 10000).toDate())
// 设置过期时间
.setExpiration(new DateTime(System.currentTimeMillis() + 60000).toDate())
// 存放各种业务数据 KV形式,value存任何信息(eg.对象转json存,请勿存放敏感信息),可以存放多个
.claim("hisenK", "hisenV")
.claim("key1", "value1")
.compact();
三、js登陆后,存储token
$.ajax({
type: "post",
url: "http://localhost:8183/login",
data: frm.serialize(),
success:function(data) {
console.log(data)
var json = jQuery.parseJSON(data);
var jwt = json.jwt;
// 登录成功,存储令牌到本地,以后每次访问,都放入header Authorization
localStorage["jwt"] = jwt;
console.log(jwt);
},
error:function(data){
console.log(data)
}
});
四、拦截器
package com.hisen.filter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.filter.GenericFilterBean;
/**
* @author hisenyuan
* @time 2018/3/16 14:40
* @description
*/
@ComponentScan
public class JwtFilter extends GenericFilterBean {
public static final String key = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545df>?N<:{LWPW_hisen";
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
//客户端将token封装在请求头中,格式为(Bearer后加空格):Authorization:Bearer +token
final String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
throw new ServletException("Missing or invalid Authorization header.");
}
//去除Bearer 后部分
final String token = authHeader.substring(7);
//解密token,拿到里面的对象claims
final Claims claims = Jwts.parser().setSigningKey(key)
.parseClaimsJws(token).getBody();
//将对象传递给下一个请求(生成时候设置的值,都可以拿出来,再放到request里面)
request.setAttribute("claims", claims);
//Object hisenK = claims.get("hisenK");
//System.out.println(hisenK);//输出:hisenV
chain.doFilter(req, res);
}
}
五、解析token
"hisenK":"hisenV"
这里面就存储了你想返回给前端的数据,一般存储用户基本信息、权限信息等
@Test
public void testDecodeJwt(){
Base64.Decoder decoder = Base64.getDecoder();
String compactJws1 = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJoaXNlbiIsImlhdCI6MTUxMjYyODUzNiwibmJmIjoxNTEyNjI4NTQ2LCJleHAiOjE1MTI2MjkxMzYsImhpc2VuSyI6Imhpc2VuViJ9.JKxvvYQyIJEN8Eg_6gN5NlnDokqVNApSd7eg3QGpjBfBARzx4ip4WRzSa0Ul2ScpdierKi9WxF1iTUdoHNRiaA";
String[] split = compactJws1.split("\\.");
System.out.println(split.length);
try {
String header = new String(decoder.decode(split[0]), "UTF-8");
String playload = new String(decoder.decode(split[1]), "UTF-8");
// signature无法解码,不是base64格式
System.out.println("header decode:"+header+"\nplayload decode:"+playload);
// header decode:{"alg":"HS512"}
// playload decode:{"sub":"hisen","iat":1512628536,"nbf":1512628546,"exp":1512629136,"hisenK":"hisenV"}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
网友评论