美文网首页jwt
前后分离(摆脱cookies & session) - JWT

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

作者: hisenyuan | 来源:发表于2018-03-16 14:56 被阅读0次

    零、基本介绍

    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();
            }
        }
    

    相关文章

      网友评论

        本文标题:前后分离(摆脱cookies & session) - JWT

        本文链接:https://www.haomeiwen.com/subject/uetrqftx.html