JWT简记

作者: KenChen_939 | 来源:发表于2021-03-02 19:54 被阅读0次

    JSON Web Token(JWT)是目前最流行的跨域认证解决方案。

    跨域认证问题及传统解决方案

    • 传统认证流程

    1. 用户向服务器发送用户名和密码。
    2. 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
    3. 服务器向用户返回一个 session_id,写入用户的 Cookie。
    4. 用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
    5. 服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。
    存在的问题:

    拓展性不好,单机可以,但是服务器集群,就要求session共享,每台服务器都能读取session
    传统解决方案:session数据持久化,写入数据库或别的持久层。

    • JWT解决方案

    1. 用户登陆时,服务端加密由用户信息和过期时间组成的字符串,得到token,发送给客户端
    2. 客户端每次发送请求时都携带token
    3. 服务端解密或验证token,从而得到用户信息和会话过期时间。

    Token结构

    image.jpeg
    • Header(头部):内部是一个JSON对象,描述JWT的元数据
    • Payload(负载):用来存放实际需要传递的数据。官方提供了七个字段,如iss、exp等,当然你也可以定义私有字段。但是要注意此处是不加密的,任何人都可以读取。
    • Signature(签名):它是对前两部分的签名。防止数据被篡改。首先需要一个密钥,这个密钥只有服务器才知道,然后使用Header里指定的签名算法算出签名。

    JWT的特点

    • JWT默认不加密
    • JWT不仅可以用于认证,也可以用于交换信息
    • 最大的缺陷:由于服务器不保存session状态,因此无法在使用过程中废止或修改某个Token,也就是说,一旦签发了,在该Token到期前会始终有效,除非服务器部署额外的逻辑。
    • JWT本身包含认证信息,一旦泄漏,任何人都可以获得该令牌的所有权限,为了减少盗用,JWT有效期应当设置的比较短。

    Token生成代码

    // 生成jwt访问令牌
    String jwtToken = Jwts.builder()
            // 用户角色
            .claim("ROLE_LOGIN", "ADMIN")
            // 主题 - 存用户名
            .setSubject(“Ken")
            // 过期时间 - 30分钟
            .setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))
            // 加密算法和密钥
            .signWith(SignatureAlgorithm.HS512, "helloworld")
            .compact();
    

    我自定义的JWT工具类

        /**
         * 检测token是否过期
         * @param claims
         * @return true:已过期,false:未过期
         */
        public static boolean isJwtExpired(Claims claims) {
            return claims.getExpiration().before(new Date());
        }
    
    
        /**
         * 解析token
         * @param token
         * @param singKey
         * @return claims
         */
        public static Claims parsingToken(String token,String singKey){
            return Jwts.parser()
                    .setSigningKey(singKey)
                    .parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX,"")).getBody();
        }
    
        /**
         * 返回username
         * @param claims
         * @return 当前token的username
         */
        public static String getUsernameFromToken(Claims claims){
            return claims.getSubject();
        }
    
        /**
         * 返回token中的权限List
         * @param claims
         * @return List<SimpleGrantedAuthority>
         */
        public static List<SimpleGrantedAuthority> getAuthFromToken(Claims claims){
            return ((List<?>) claims
                   .get("rolue")).stream()
                   .map(authority -> new SimpleGrantedAuthority((String) authority ))
                   .collect(Collectors.toList());
        }
    

    相关文章

      网友评论

          本文标题:JWT简记

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