JWT-JSON Web Token

123 阅读3分钟

image.png JSON Web Token是一个开源的、遵循RFC 7519工业标准的方法,用于以JSON对象的方式,安全的表示服务器端、客户端双方之间的信息传输。JWT官网地址为:jwt.io/。 JWTs作为一种凭证,可以授予资源的访问权限。JWT并不会存储令牌本身,并且所有的验证和调试操作都在客户端完成。

JWT加密算法

JWT提供了如下图所示的、对于令牌的加密/解密算法,通过这种加密/解密算法,可以以不同的方式对用户的信息进行编码/解码操作。

image.png

编码&解码

image.png 如下图所示,以SH256算法,将以上用户信息进行编码,得到左侧部分的Token令牌,这个令牌将被从Java服务器端发送到浏览器客户端;对于持有左侧(经SH256算法编码的)Token令牌的客户端,当它在向服务器端发起请求时,Java后端就可以通过相同的SH256算法,将其解码为原始的用户信息。这就是利用JWT算法进行编码和解码操作的基本过程。 image.png

JWT的组成

JWT由三部分组成,包括:头部(Header)、载荷(Payload)、签名(Signature),将这3个部分以特定的算法进行编码处理,并使用“.”-点符号连接起来,就得到一个JWT字符串,也即:Token令牌。

头部(Header)

JWT的头部包括::token的类型(“JWT”)和加密/解密算法名称(比如:HMAC SHA256或者RSA等等)。如下图所示, image.png

载荷(Payload)

载荷(payload)主要用来包含声明(claims ),这个声明一般是关于实体(通常是用户)和其他数据的声明,例如:用户信息,如下图所示,

image.png

签名(Signature)

签名(Signature),得到前两部分,即:头部(Header)和载荷(Payload)之后,就需要将这两部分拼接完的字符串用HS256算法进行加密,在加密的时候,还需要提供一个密钥(secret),将其加密处理之后的也得到一个字符串,这个字符串就是签名(Signature)。

image.png

JWT的实现版本

image.png JWT提供了不同语言版本的依赖库,如:C#、Python、Java、Node.js等等,其官网地址为:jwt.io/libraries

JWT与Java项目的整合

依赖引入

对于Maven项目,可以直接将JWT(GitHub地址:github.com/auth0/java-… 的依赖坐标配置到pom.xml文件中即可,如下,

<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>4.2.1</version>
</dependency>

创建&验证JWT

工具类封装

public class XJWTool {
    //properties
    private static final Integer EXPIRED_TIME = 60*1;//过期时长
    private static final String SECRET = "hdsakdsald,asd16dasd465adankga15hdfgsfa";//jwt 密钥

    //methods

    /**
     * 根据Claim声明获取Token
     * @param map 包含<key,value>的键值对属性
     * @return String字符串格式的Token
     */
    public static String getToken(Map<String,String> map){
        //创建Algorithm算法
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE,EXPIRED_TIME);
        //创建Token
        JWTCreator.Builder builder = JWT.create();
        //添加Claim声明
        map.forEach(builder::withClaim);
        //指定过期时间
        builder.withExpiresAt(calendar.getTime());
        //指定算法-生成Token
        return builder.sign(algorithm);
    }

    /**
     * 验证token的合法性
     * @param token token令牌值
     * throw 抛出异常-表示验证失败
     */
    public synchronized static void decodeToken(String token){
        JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }

    /**
     * 获取token信息的方法
     * @param token token令牌值
     * @return DecodedJWT对象
     * throw 抛出异常-表示验证失败
     */
    public synchronized static DecodedJWT getTokenInfo(String token){
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
        return decodedJWT;
    }
}

示例代码

@Test
public void JWTTool_Test(){
    Map<String,String> map = new HashMap<>();
    map.put("name","Tom");
    map.put("password","123456");
    map.put("age","30");

    String token = XJWTool.getToken(map);
    System.out.println(token);

    //验证Token
    XJWTool.decodeToken(token);

}

image.png