【JWT】令牌-概述&&基本使用

JWT令牌的使用

1. 需求

​ 在实现系统登录功能的时候,我们需要实现用户完成一次登录之后,在后续的请求中不再需要反复登录,以前我们经常用到的技术是session

  • 即用户发出登录的请求到服务器。
  • 验证成功之后,创建session对象(用于存储数据)。
  • 服务器返回一个session对象的id到浏览器,浏览器以cookie的形式存储到浏览器端
  • 后续的浏览器的请求都携带这个cookie访问服务器就可以实现多次请求间的数据共享,包括登录状态

Alt

Alt

但是使用session存在以下缺点:

  1. session中与用户的会话数据是保存在服务器的内存中的,当session中的数据越来越大,会降低服务器运行的性能
  2. session无法用于集群环境,因为session是存储的服务器端的,这样子虽然安全,但集群环境中一般会布置多台服务器,用户在浏览器端二次请求使用的sessionID访问的不是第一次请求的服务器,就无法获取到session中的数据
  3. session底层是基于cookie实现的,cookie无法实现跨域(域指的是域名,即网址,只要协议、IP地址和端口号任意一个不同即为跨域)且cookie无法在移动端使用,这是浏览器出于安全禁止的。

​ 这时, JWT令牌技术就问世了,令牌技术将上面的问题基本都解决了,如下

  • 跨域问题:
    jwt令牌是无状态的,jwt令牌的编码所用的信息就有用户信息(如用户名和用户id等非敏感信息),因此,服务器不需要存储跟用户的会话信息,对jwt令牌解析之后,就可以确定该请求是否来自同一端,确保了服务器的安全问题。
    在跨域请求中,浏览器会自动检查请求的来源,如果不是同源的请求,会触发跨域安全机制导致请求被阻止。但通过使用令牌技术,可以将令牌作为请求的一部分发送,服务器接收到请求时会验证令牌的有效性,从而允许跨域请求。
  • 服务器存储压力:jwt令牌存储在浏览器端
  • PC和移动端都可以使用

2. 是什么

​ jwt令牌本质是一串字符串,由三部分组成,类似"xxx.yyy.zzz",前两部分(xxx.yyy)由json对象经过base64编码而来,“zzz”部分属于签名(通过加密算法和密钥生成的),jwt令牌由编码和加密而来,jwt令牌也可以被解析获取json对象中的信息,解析失败一般会导致程序的报错。
​ (参考课程笔记:javaweb)JWT的组成: (JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)

  • 第一部分:Header(头), 记录令牌类型、签名算法等。 例如:{“alg”:“HS256”,“type”:“JWT”}

  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{“id”:“1”,“username”:“Tom”}

  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。

3. 工作流程

Alt

4. 怎么用

  1. 导入maven坐标,junit不是一定要导入,后续只是用作测试

    		<dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>
    
    		 <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
                <scope>test</scope>
            </dependency>
    
  2. 创建令牌(注意密钥的长度要稍微大点)

    @Test
        public void testGetJwt() {
    
    
            //模拟浏览器发请求携带的用户信息
            Map<String, Object> claims = new HashMap<>();
            claims.put("username", "aimin");
            claims.put("password", "123456");
    
            String jwtToken = Jwts.builder()
                    //设置签名加密算法和密钥
                    .signWith(SignatureAlgorithm.HS256, "aimin")
                    //设置声明,里面可以是一些自定义的信息
                    .setClaims(claims)
                    //设置token过期时间
                    .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
                    //添加JWT 字符串由三部分组成,它们通过句点 . 分隔开来,分别是头部(Header)、载荷(Payload)、签名(Signature)。compact() 方法的作用是将这三部分合并成一个完整的 JWT 字符串,以便在网络传输中使用。
                    .compact();
            System.out.println(jwtToken);
    
        }
    
  3. 解析令牌

     @Test
        public void testParserJwt(){
    
            Map<String, Object> claims = Jwts.parser()
                    //输入密钥
                    .setSigningKey("aimin")
                    //输入令牌        		    .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjEyMzQ1NiIsImV4cCI6MTcxMjUwNTQ0MCwidXNlcm5hbWUiOiJhaW1pbiJ9.2V277eqJo3gxiRgrxM3JbbKku6qez2WgsJ5dCE9kZP8")
                    .getBody();
    
            		System.out.println(claims);
    
    
        }
    

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值