JWT简记

2021-03-02  本文已影响0人  KenChen_939

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

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

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

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

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

Token结构

image.jpeg

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());
    }
上一篇下一篇

猜你喜欢

热点阅读