【JWT】概念与应用场景解析

1.什么是JWT?

        JWT全称JSON WEB TOKEN,是一种经过加密的包含非敏感信息具有时效性的固定格式字符串

2.JWT的组成?

        既然它是JSON,那么它必然满足JSON的格式;JWT由headerpayloadsignature三部分共同组成。

        header : {"alg" : HS256,"typ" : JWT}   主要存储加密算法alg、数据类型typ等元数据

        payload:主要存储需要进行传输的非敏感信息,如用户的名称、角色等

        signature:由header与payload经过base64编码后得到的字符串,使用header中声明的加密算法对字符串进行加密后得到

3.JWT的作用及应用场景?

        作用:JWT的设计目的就是在服务器不存储用户信息、状态的情况下,安全的传递非敏感数据

        应用场景:根据JWT的作用,我们可以在解决客户端访问服务器时的身份认证问题时引入JWT

4.为什么JWT能安全的传递非敏感数据?

        JWT使用Base64编码方式对header、payload编码是众所周知的,那我们在截取了JWT后,进行反编码获取header中存储的加密算法,再使用相同算法伪造JWT访问服务器,服务器改如何辨别呢?

        这时候就要引入密钥的概念了,在使用加密算法对编码后的header、payload进行加密时还使用了密钥,而密钥保证了只知道加密算法的情况下,无法对signature进行解密

        我们可以把密钥想象成一个方法的参数、加密算法是一个方法,不同的传参,方法的执行结果或返回值肯定不同,而关键之处就在于:密钥只被服务器(也就是生成JWT的一端)持有

5.传统cookie/session与JWT有什么不同?

        (1)传统cookie/session是在用户登录后,在服务器内存中保存一个session“会话”,“会话”里维护了用户相关信息;每个session生成后会有一个sessionID,服务器会将sessionID返回给客户端,客户端拿到sessionID后,接下来的每一次请求会把sessionID放在cookie中,由服务器通过sessionID查找对应session,对请求进行鉴权。

                 JWT虽然也是由服务器生成,但它不会保存在自己的内存中,而是由客户端进行保存,好处是服务器不会有内存溢出的风险。像cookie/session这种方式,在用户流量较大时,服务器的内存可能会溢出

        (2)传统cookie/session无法解决集群模式下,不同服务器节点无法共享session的问题。每一台服务器的session都有属于自己的“域”,无法共享;如果用户在登录后,其用户信息被保留在集群的其中一台服务器节点中,它随后的请求被负载均衡到了其它服务器节点,由于session不能共享、用户也没有在其它服务器保存session,那么在访问一些需要登录的接口时,用户就需要重新登录,极大地影响用户体验

                  JWT不会存在上述问题,因为服务器获取到这个token之后进行JWT解析来读取用户数据,如果没有数据就代表没有登录,有数据且未失效,则身份认证通过,拦截器放行。

6.JWT的使用

        (1)依赖导入:

       

 
            io.jsonwebtoken
            jjwt
            0.9.0
        

        (2)配置文件(注意yaml格式):

        

token:
                    # 令牌自定义标识
                    header: Authorization
                    # 令牌密钥
                    secret: 123
                    # 令牌有效期(默认30分钟)
                    expireTime: 30

        (3)创建JWT:

        

JwtBuilder builder = Jwts.builder();
            return builder
            // header
            .setHeaderParam("typ","JWT")
            .setHeaderParam("alg","HS256")
            // payload
            .claim("username","tom")
            .claim("userId","123")
            // expire time
            .setExpiration(new Date(System.currentTimeMillis + oneDat))
            // signature
            .signWith(SignatureAlgorithm.HS256,base64EncodeSecretKey) //加密算法和密钥
            .compact();

        (4)解析JWT:

       

 try{
      JwtParser parser = Jwts.parser();
      Jws claimsJws =       parser.setSigningKey(base64EncodedSecretKey).parseClaimsJws(jwt);
      Claims claims = claimsJws.getBody();
      println(claims.get("username"));
      println(claims.getExpiration());
    }catch(JwtException e){
        //handle exception
    }

你可能感兴趣的:(安全,java)