如何使用jwt生成token


jwt应该如何使用呢?

下面来写一个最简单的jwt的使用demo

1. 引入依赖包:

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

2. 加密解密方法

public static void main(String[] args) {
        // 过期时间
        final Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, 1000);
        
        // 以abc为密钥进行hmac256方法加密,保存 a,b两个属性
        final String token = JWT.create().withHeader(new HashMap<>())
                .withClaim("a", "ccc")
                .withClaim("b", JSONObject.toJSON(Arrays.asList("a", "b", "c")).toString())
                .withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256("abc"));
        System.out.println("token = " + token);

        // 解密
        JWTVerifier build = JWT.require(Algorithm.HMAC256("abc")).build();
        final DecodedJWT verify = build.verify(token);
        // 取出a
        final Claim a = verify.getClaim("a");
        System.out.println("a = " + a);
        System.out.println("a.asString() = " + a.asString());

        // 取出b
        final Claim b = verify.getClaim("b");
        System.out.println("b = " + b);
        System.out.println("b.asArray(List.class) = " + b.asString());

        // 取出过期时间
        final Date expiresAt = verify.getExpiresAt();
        System.out.println("expiresAt = " + expiresAt.toLocaleString());

    }

 

在生产环境中,一般jwt会保存用户的名字和角色权限等信息。可以将token 写到cookie里,每次前端访问后台时,可以在拦截器或者过滤器取到token, 然后解密,先判断是否过期,过期就抛异常阻止其访问。然后取出信息保存到threadLocal里,方便以后调用这些信息,当后台访问完成后,从thredLocal删除此用户信息。

3. 如何使用

登陆返回JWT, 客户端浏览器拿到这个 JWT 字符串后,存储到 cookie 或者 浏览器的 LocalStorage 中。再次发送请求,比如请求用户设置页面的时候,在 HTTP 请求头中加入 JWT 字符串,或者直接放到请求主体中。

登录过后给前端进行返回JWT并设置了过期时间30分钟,后端接收请求的时候获取请求头出来进行jwt解析判断过期时间是否小于10分钟,如果小于10分钟就生成新的 jwt 在responseHearde进行返回即可,前端每次都检查responseHearde是否有jwt, 如果有,则替换localStorage 中的jwt .

 

 

 

 

 

 

jwt 结构解析

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)

Header

JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择

iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

 这些预定义的字段并不要求强制使用。除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中

{ "sub": "1234567890", "name": "Helen", "admin": true ,roles:["admin","comsumer"]}

Signature

签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。

在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用.分隔,就构成整个JWT对象

注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:

header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据
signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。注意secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值 

 

JWT 有效期内可以

JWT 有个问题,那就是一旦颁发一个 JWT 令牌,服务端就没办法废弃掉它,除非等到它自身过期。有很多应用默认只允许最新登录的一个客户端正常使用,不允许多端登录,JWT 就没办法做到,因为颁发了新令牌,但是老的令牌在过期前仍然可用。这种情况下,就需要服务端增加相应的逻辑。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM