Bootstrap

JWT token令牌使用

JWT token令牌使用

一,什么是JWT?

JWT简称 json web token, 也就是通过JSON形式作为Web应用中的令牌,用于各方之间安全地将信息作为JSON格式进行传输。在传输过程中可以完成数据的加密,签名等相关处理。

二,JWT能做什么?
1,授权

当用户登录后,后续请求将包括JWT(可以放置于请求头或者cookies),从而允许用户进行相关的接口调用操作资源。单点登录也是常用的JWT控制手段之一(唯一用户同一时间只能有唯一合法的JWT认证token)

2,信息传输

你可以将你需要传递的信息加密封装到 JWT token中使用,当接收方收到token解密后可以获取token中传递的附属信息(如:用户角色,权限等)。由于签名是使用标头和有效负载计算的,因此我们还可以验证内容是否被篡改。

三,认证流程

1,前端将自己的用户名密码发到后端接口,一般是POST请求+HTTPS的SSL加密传输。

2,后端核对用户名,密码成功后,将用户的信息作为JWT 的payload,将其与头部分别进行Base64编码拼接后签名,生成一个JWT token(xxx.yyy.zzz的字符串)

3,后端将JWT字符串作为登录成功的结果返回给前端,前端将返回结果保存在localStorage或sessionStorage上。退出登录时删除保存的JWT即可。

4,前端在后续每次请求时将JWT放到HTTPS的Header中,进行后续的访问。

5,后端在后续接口的调用中检查JWT的有效性和时效性。

6,验证通过,进行操作。

四,JWT的结构
token  string ==》 header.payload.singnature
JWT token字符串     标头    有效负载   签名
Header
标头通常由两部分组成: 令牌的类型和所使用的签名算法(HMAC, SHA256或RSA),使用Base64编码组成JWT的第一部分。
​
Payload
开发人员设置的存储用户信息的负载(一般为用户所拥有的角色,权限等信息,不要放敏感信息,如密码等)使用Base64编码组成JWT的第二部分。
​
Singature
前面两部分都是使用Base64进行编码,可以解密知道里面的信息,签名需要使用编码后的header和payload以及一个密钥,然后用header中指定的签名算法进行签名。
如: HMACSHA256(base64UrlEncode(header)+ "." + base64UrlEncode(payload), secret);
最后一步的签名是为了安全,防止内容被篡改。
​
五,简单使用JWT
1,引入依赖
<!--    引入JWT-->
    <dependency>
      <groupId>com.auth0</groupId>
      <artifactId>java-jwt</artifactId>
      <version>3.4.0</version>
    </dependency>
2, 生成JWT token
    String sign = "adjuqbnvbnqkjnmweijn2154185q1aS'd.q";
​
    HashMap<String, Object> header = new HashMap<>();
    //1, 生成JWTtoken
    public String generateJWT() {
        header.put("typ", "JWT");
        String token = JWT.create().withHeader(header)  // header这步可以省略
                .withClaim("name", "张三") // 设置有效负载
                .withClaim("age", 15)
                .sign(Algorithm.HMAC256(sign));
        System.out.println(token);
        return token;
    }

生成如下:

3,解析token
public void parsingJWT(String token) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
    DecodedJWT jwt = JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
    System.out.println(jwt.getPayload());
    System.out.println(jwt.getClaim("name").asString());
    System.out.println(format.format(jwt.getExpiresAt().getTime()));
}
​
// 执行
    public static void main(String[] args) {
        JWTTest jwtTest = new JWTTest();
        String token = jwtTest.generateJWT();
        jwtTest.parsingJWT(token);
    }

结果如下:

3,验证token是否有效或者是否过期
    public Boolean tokenIsExpires(String token) {
        try {
            JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

测试

    public static void main(String[] args) throws InterruptedException {
        JWTTest jwtTest = new JWTTest();
        String token = jwtTest.generateJWT();
        jwtTest.parsingJWT(token);
        TimeUnit.SECONDS.sleep(6);
        Boolean isExpires = jwtTest.tokenIsExpires(token);
        if (isExpires) {
            System.out.println("当前token还没过期");
        } else {
            System.out.println("当前token已经过期了");
        }
    }

结果

;