前后分离(摆脱cookies & session) - JWT

零、基本介绍

jwt是一种令牌,生成需要一个密钥,经过加密算法,得到一个token
格式:header.playload.signature
样例:eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJoaXNlbiIsImlhdCI6MTUxMjYyODUzNiwibmJmIjoxNTEyNjI4NTQ2LCJleHAiOjE1MTI2MjkxMzYsImhpc2VuSyI6Imhpc2VuViJ9.JKxvvYQyIJEN8Eg_6gN5NlnDokqVNApSd7eg3QGpjBfBARzx4ip4WRzSa0Ul2ScpdierKi9WxF1iTUdoHNRiaA
如果前端传给后台被修改的数据或者过期的数据,是无法校验通过的

签到拿到token之后,是可以经过base64解密,拿到 header.playload里面的信息(详情见第五步:解析token)

一、引入的包

    
    
      io.jsonwebtoken
      jjwt
      0.9.0
    

二、jwt生成

      public static final String key = "XX#$%()(#*!()!KL<>?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<>?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();
        }
    }

你可能感兴趣的:(前后分离(摆脱cookies & session) - JWT)