JWT技术快速入门

JWT是一种用于安全传输信息的开放标准,常用于用户身份验证和授权。它由标头、有效载荷和签名三部分组成,通过数字签名确保完整性。在登录后,JWT作为令牌响应给用户,用于后续API请求的认证。JWT不存储用户信息,而是携带必要的权限数据,提高系统的可伸缩性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景介绍

JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为 JSON 对象。此信息可以验证和信任,因为它是数字签名的。JWT 可以使用密钥(使用HMAC算法)或使用RSAECDSA的公钥/私钥对进行签名。

虽然 JWT 可以加密以在各方之间提供保密性,但专注于签名令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌会向其他方隐藏这些声明。当使用公钥/私钥对令牌进行签名时,签名还证明只有持有私钥的一方才是签署它的一方。

总结:JSON Web token简称JWT, 是用于对应用程序上的用户进行身份验证的标记。也就是说, 使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他session数据。此特性便于可伸缩性, 同时保证应用程序的安全;

本质:JWT本质就是一个字符串,是一个经过加密算法加密和校验后的字符串。

官网:JSON Web Tokens - jwt.io

官网截图:

应用场景:

  • 授权使用 JWT 最常见的场景。主要用于用户登录后,每个后续请求都将包含 JWT,从而允许用户访问该令牌允许的服务和资源等。

  • 信息交换:JSON Web 令牌是进行安全传输信息的好方法。因为可以对 JWT 进行签名(例如,使用公钥/私钥对),所以您可以确定发件人就是他们所说的那个人。此外,由于使用标头和有效负载计算签名,还可以进行验证内容没有被篡改。

流程图

 解析:

1、客户端初次登陆时,发送登录请求带客户客户端,登陆成功后创建JWTtoken,再将生成的token 响应给用户,token记录到客户端本地;

2、客户端访问其他接口时,发送受保护的API请求,请求authorzationHeader中添加token信息;

3、通过token获取信息,校验token的合法性,检查是否有被篡改过;

4、经过校验无误后,返回响应;

主要构成部分:

JWT是以( . )进行分隔的三部分组成

  1. 标头(头部信息)——主要是令牌的类型和所要使用的加密算法
  2. 有效载荷(数据)——用于用户数据的设置,采用JSON格式进行存储
  3. 自定义签名——用于自定义私钥,从而保证数据的安全高效

示例:

xxxxx . yyyyy . zzzzz     

JWT 由标头、有效载荷、自定义签名 三者构成一个整体

1、标头:令牌类型+所要使用的加密算法

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

图例:

 然后,这个 JSON 被Base64Url编码以形成 JWT 的第一部分。

2、有效载荷(数据):主要是存储的有效数据

{
  "userID": "1234567890",
  "name": "zhangsan",
  "phone": "13312345678"
}

 然后对有效负载进行Base64Url编码以形成 JSON Web 令牌的第二部分。

图例:

请注意! ! !   对于已签名的令牌,此信息虽然受到保护以防篡改,但任何人都可以读取。除非已加密,否则请勿将机密信息放入 JWT 的有效负载或标头元素中。

3、自定义签名:自定义的签名私钥,是前两个(标头(头部信息)、有效载荷(承载数据))加密而成,进行校验,用于进一步保障数据的安全。

例如,如果想使用 HMAC SHA256 算法,签名将通过以下方式创建:

 

示例 生成的JWT加密数据

 

案例举证

1、pom文件中导入相关依赖

 <!--jwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

2、编写测试案例

2-1生成token 进行数据加密

 @Test
    public void testtoken(){
        //准备数据
        HashMap map = new HashMap();
        map.put("id",1001);//存入数据
        map.put("name","zhangsan");//存入数据
        map.put("phone","13312345678");  //存入数据
        //使用JWT工具生成token
        long now = System.currentTimeMillis();//获取当前系统时间
        // LocalDate now1 = LocalDate.now();//获取当前系统时间
        String token = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "zhangsan666") //指定加密算法和自定义私钥
                .setClaims(map)                                //放入数据
                .setExpiration(new Date(now + 30000))  //设置失效时间 30000ms
                .compact();
        System.out.println(token); //输出加密后的JWT结果

    }

结果图例:

2-2解析Token

//解析token

    /**
     * SignatureException : token不合法
     * ExpiredJwtException:token已过期
     */
    @Test
    public void testParseToken() {
        //加密后的JWT数据
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJwaG9uZSI6IjEzMzEyMzQ1Njc4IiwibmFtZSI6InpoYW5nc2FuIiwiaWQiOjEwMDEsImV4cCI6MTY1ODkxNjk3Mn0.CnVGDRVhUpR9VkVK7eLpDLSHhFEw9Ad0ww_CcPV15Ak";
        try {
            Claims claims = Jwts.parser()   //进行解析
                    .setSigningKey("zhangsan666")  //自定义私钥
                    .parseClaimsJws(token)
                    .getBody();           //数据部分
            Object id = claims.get("id");    //获取数据部分的主键
            Object name = claims.get("name");
            Object phone = claims.get("phone");
            System.out.println(id + "--" +name+"--"+"--"+phone); //输出结果
        }catch (ExpiredJwtException e) {
            System.out.println("token已过期");  //超出失效时间,则抛出异常,输出token已过期
        }catch (SignatureException e) {
            System.out.println("token不合法"); //如果jwt加密数据被手动篡改,则抛出异常,输出token不合法
        }
    }

解码图例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值