JWT令牌 创建JWT、和解析JWT

JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌。

JWT的使用场景:

  • 一种情况是webapi,类似之前的阿里云播放凭证的功能

  • 另一种情况是多web服务器下实现无状态分布式身份验证

JWT的作用:

  • JWT 最重要的作用就是对 token信息的防伪作用

JWT的原理:

  • 一个JWT由三个部分组成:JWT头、有效载荷、签名哈希最后由这三者组合进行base64编码得到

  • 该对象为一个很长的字符串,字符之间通过"."分隔符分为三个子串。

  • 每一个子串表示了一个功能块,总共有以下三个部分:JWT头、有效载荷和签名

JWT头部分是一个描述JWT元数据的JSON对象,通常如下所示。

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

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

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

sub: 主题
iss: jwt签发者
aud: 接收jwt的一方
iat: jwt的签发时间
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

以上默认字段外,我们还可以自定义私有字段,如下例

{
  "name": "Helen",
  "admin": true,
  "avatar": "helen.jpg"
}

请注意,默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。

JSON对象也使用Base64 URL算法转换为字符串保存。

签名哈希

签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

首先,需要指定一个密码(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(claims), secret)    ==>   签名hash

使用

1.引入pom

 <dependencies>
        <!-- JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

    </dependencies>

2.创建JWT、和解析JWT

public class JwtTests {

    //过期时间,毫秒,24小时
    private static long tokenExpiration = 24*60*60*1000;
    //秘钥
    private static String tokenSignKey = "atguigu123";


    //创建JWT
    @Test
    public void testCreateToken(){
        //JWT  由三部分组合 头 载荷 签名哈希
        String token = Jwts.builder()
                //头
                .setHeaderParam("typ", "JWT") //令牌类型
                .setHeaderParam("alg", "HS256") //签名算法

                //载荷 :默认信息
                .setSubject("guli-user") //令牌主题
                .setIssuer("atguigu")//签发者
                .setAudience("atguigu")//接收者
                .setIssuedAt(new Date())//签发时间
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) //过期时间
                .setNotBefore(new Date(System.currentTimeMillis() + 20*1000)) //20秒后可用
                .setId(UUID.randomUUID().toString())//jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

                //载荷 :自定义信息
                .claim("nickname", "Helen")
                .claim("avatar", "1.jpg")

                //签名哈希
                .signWith(SignatureAlgorithm.HS256, tokenSignKey)//签名哈希

                //组装jwt字符串
                .compact(); //转换成字符串

        System.out.println(token);
    }


    解析JWT
    @Test
    public void testGetUserInfo(){

        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJndWxpLXVzZXIiLCJpc3MiOiJhdGd1aWd1IiwiYXVkIjoiYXRndWlndSIsImlhdCI6MTY5MTIyMDc5NywiZXhwIjoxNjkxMzA3MTk3LCJuYmYiOjE2OTEyMjA4MTcsImp0aSI6Ijk1ZmEyNzBhLTg2NTQtNDRiNy1iMzkzLTYzYWJiYmE1ODBhMSIsIm5pY2tuYW1lIjoiSGVsZW4iLCJhdmF0YXIiOiIxLmpwZyJ9.4AMALjh5zrQCt4l09uM4g3b3PkUwqhUSVWHeEjLMNt0";
        Jws<Claims> claimsJws = Jwts.parser()//生成解析器
                .setSigningKey(tokenSignKey)//使用密钥解析
                .parseClaimsJws(token);//放入token

        Claims claims = claimsJws.getBody();//有校载荷部分

        //取出载荷默认部分
        String subject = claims.getSubject();
        String issuer = claims.getIssuer();
        String audience = claims.getAudience();
        Date issuedAt = claims.getIssuedAt();
        Date expiration = claims.getExpiration();
        Date notBefore = claims.getNotBefore();
        String id = claims.getId();

        System.out.println(subject);
        System.out.println(issuer);
        System.out.println(audience);
        System.out.println(issuedAt);
        System.out.println(expiration);
        System.out.println(notBefore);
        System.out.println(id);;

        String nickname = (String)claims.get("nickname");//取出载荷自定义部分
        String avatar = (String)claims.get("avatar");//取出载荷自定义部分

        System.out.println(nickname);
        System.out.println(avatar);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Java中解析JWT令牌可以使用jjwt库。jjwt是一个提供JWT创建和验证的Java库,它是免费和开源的(Apache License, Version 2.0)。使用jjwt非常容易理解和使用。你可以通过在Maven中添加jjwt的依赖来使用它,具体的Maven坐标如下: ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` 一旦你添加了jjwt的依赖,你可以使用Jwts.builder()来创建一个JWT令牌,并通过添加一些简单的用户信息来定制令牌。你还可以选择一个加密算法来创建令牌。要解析JWT令牌,你可以使用Jwts.parser()方法。详细的JWT入门案例和Spring Boot集成JWT实现令牌鉴权的教学视频可以参考相关文档和教程。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Java权限认证机制之JWT令牌生成和解析以及SpringMVC参数解析器](https://blog.csdn.net/baidu_39378193/article/details/126619014)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [jwt](https://download.csdn.net/download/weixin_42131728/15345005)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值