JavaWeb 令牌技术-JWT令牌

本文介绍了JWT(JSONWebToken)的概念、组成、工作原理,以及在登录认证中的应用,包括如何生成和校验JWT令牌,以及注意事项。
摘要由CSDN通过智能技术生成

jwt

全称:JSON Web Token

介绍:定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的

  • 简洁:是指jwt就是一个简单的字符串。可以在请求参数或者是请求头当中直接传递。

  • 自包含:可以根据自身的需求在jwt 令牌中存储自定义的数据内容。如:可以直接在jwt令牌中存储用户的相关信息。

  • 简单来讲,jwt就是将原始的json数据格式进行了安全的封装,这样就可以直接基于jwt在通信双方安全的进行信息传输了

  • JWT的组成:(JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)在这里插入图片描述

    • 第一部分:Header(头)
      • 记录令牌类型、签名算法等。
      • 如{“alg”:“HS256”,“type”:“JWT”}
    • 第二部分:Payload(有效载荷)
      • 携带一些自定义信息、默认信息等。
      • 如{“id”:“1”,“username”:“Tom”}
    • 第三部分:Signature(签名)
      • 防止Token被篡改、确保安全性。
      • headerpayload,并加 入指定秘钥,通过指定签名算法计算而来。
      • **签名的目的:**为了防jwt令牌被篡改
        • 因为jwt令牌最后一个部分数字签名的存在, 所以整个jwt 令牌是非常安全可靠的。一旦jwt令牌当中任何一个部分、任何一个字符被篡改了,整个令牌在校验的时候都会失败,所以它是非常安全可靠的。
  • JWT是如何将原始的JSON格式数据,转变为字符串

    • 在生成JWT令牌时,对JSON格式的数据进行一次base64编码

      注意:Base64是编码方式,而不是加密方式

      • 【base64】

        • 是一种基于64个可打印的字符来表示二进制数据的编码方式

        • 任何数据经过base64编码之后,最终就会通过这64个字符来表示

        • 所使用的64个字符分别是A到Z、a到z、 0- 9,一个加号,一个斜杠.

          当然还有等号。等号它是一个补位的符号

  • jwt令牌的应用场景—登录认证在这里插入图片描述

    • 在浏览器发起请求来执行登录操作,此时会访问登录的接口,如果登录成功之后,我们需要生成 一个jwt令牌,将生成的 jwt令牌返回给前端
    • 前端拿到jwt令牌之后,会将jwt令牌存储起来。在后续的每一次请求中都会将jwt令牌携带到服务端。
    • 服务端统一拦截请求之后,先来判断一下这次请求有没有把令牌带过来,如果没有带过来,直接拒绝访问,如果带过来了,还要校验一下令牌是否是有效。如果有效,就直接放行进行请求的处理。

jwt令牌的生成和校验

  • 使用JWT令牌,需要先引入JWT的依赖

    <!-- JWT依赖-->
     <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
     </dependency>
    

    在引入完JWT来赖后,就可以调用工具包中提供的API来完成JWT令牌的生成和校验

    工具类:Jwts

  • 生成JWT代码
    • 生成JWT令牌字符串

      String jwt=Jwts.builder()
      			   .setClaims(Map对象) 自定义内容(载荷)
             		   .signWith(签名算法, 密钥字符串) //签名算法
          		   .setExpiration(Date对象)  //有效期
          		   .compact();
      
  • 解析生成的JWT令牌
    • 获得Claims对象

      Claims claims=Jwts.parser()
      				  .setSigningKey(密钥字符串)//指定签名密钥
                                                  //必须保证和生成令牌时使用相同的签名密钥
          			  .parseClaimsJws(jwt令牌字符串)
          			  .getBody();
      
  • 案例代码:jwt令牌的生成与解析

    @Test
     public void genJwt(){
         //定义有效载荷,即所需要携带的内容
        Map<String,Object> claims = new HashMap<>();
        claims.put(“id”,1);
        claims.put(“username”,Tom);
         //生成JWT令牌字符串
        String jwt = Jwts.builder()
            .setClaims(claims) //自定义内容(载荷)          
            .signWith(SignatureAlgorithm.HS256, “itheima”) //签名算法     
            .setExpiration(new Date(System.currentTimeMillis() + 60*1000)) //有效期60秒   
            .compact();
        //输出结果
        System.out.println(jwt);
     }
    
    //假如输出结果如下:
    //eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjczMDA5NzU0fQ.RcVIR65AkGiax-ID6FjW60eLFH3tPTKdoK7UtE4A1ro
    
     @Test
     public void parseJwt(){
         //解析生成的JWT令牌
         Claims claims = Jwts.parser()
            .setSigningKey("itheima")//指定签名密钥
            .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjczMDA5NzU0fQ."+
                            "RcVIR65AkGiax-ID6FjW60eLFH3tPTKdoK7UtE4A1ro")
            .getBody();
         //输出结果
         System.out.println(claims);
     }
            
    
    • 使用JWT令牌时需要注意:
      • JWT校验时使用的签名秘钥,必须和生成JWT令牌时使用的秘钥是配套的。
      • 如果JWT令牌解析校验时报错,则说明 JWT令牌被篡改失效了,令牌非法。
  • 登录下发令牌

    登录成功之后生成JWT令牌,并且把令牌返回给前端

    • 【注意】用户登录成功后,系统会自动下发JWT令牌,然后在后续的每次请求中,都需要在请求头header 中携带到服务端,请求头的名称为 token ,值为登录时下发的JWT令牌。

    • 实现步骤:

      • 引入依赖

      • 编写JWT工具类(JwtUtils类),并将其放入项目的utils包(自定义的)下【一般直接引用就可以,代码变化不大】

         public class JwtUtils {
         private static String signKey = "yeye";//签名密钥
         private static Long expire = 43200000L; //有效时间
            /**
             * 生成JWT令牌
             * @param claims JWT第二部分负载 payload 中存储的内容
             * @return
             */
         public static String generateJwt(Map<String, Object> claims){
            String jwt = Jwts.builder()
                        .addClaims(claims)//自定义信息(有效载荷)
                        .signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部)
                 .setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间
                        .compact();
                return jwt;
            }
             
            /**
             * 解析JWT令牌
             * @param jwt JWT令牌
             * @return JWT第二部分负载 payload 中存储的内容
             */
            public static Claims parseJWT(String jwt){
                Claims claims = Jwts.parser()
                        .setSigningKey(signKey)//指定签名密钥
                        .parseClaimsJws(jwt)//指定令牌Token
                        .getBody();
                return claims;
            }
         }
        
      • 编写代码,实现登录完成后,调用工具类生成JWT令牌并返回

        @RestController
        @Slf4j
         public class LoginController {
            //依赖业务层对象
            @Autowired
            private EmpService empService;
            @PostMapping("/login")
            public Result login(@RequestBody Emp emp) {
                //调用业务层:登录功能
                Emp loginEmp = empService.login(emp);
                //判断:登录用户是否存在
        		if(loginEmp !=null ){
         		//自定义信息
        		Map<String , Object> claims = new HashMap<>();
        		claims.put("id", loginEmp.getId());
         		claims.put("username",loginEmp.getUsername());
         		claims.put("name",loginEmp.getName());
         		//使用JWT工具类,生成身份令牌
        		String token = JwtUtils.generateJwt(claims);
         		return Result.success(token);
          	}
         	return Result.error("用户名或密码错误");
          }
        }
        

        登录请求完成后,可以看到JWT令牌已经响应给了前端,此时前端就会将JWT令牌存储在浏览器本地在这里插入图片描述

        发起一个查询部门数据的请求,此时可以看到在请求头中包含一个token(JWT令牌),后续的每一次请求当中,都会将这个令牌携带到服务端在这里插入图片描述

参考文献:黑马javaWeb视频

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值