【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);
    
    
        }
    

相关推荐

  1. SpringBoot项目使用JWT令牌进行权限校验

    2024-04-09 20:32:02       54 阅读
  2. JWT令牌(Token)设计

    2024-04-09 20:32:02       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-09 20:32:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-09 20:32:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-09 20:32:02       82 阅读
  4. Python语言-面向对象

    2024-04-09 20:32:02       91 阅读

热门阅读

  1. 如何判断一个linux机器是物理机还是虚拟机

    2024-04-09 20:32:02       35 阅读
  2. Docker详细安装与使用教程:从入门到实践

    2024-04-09 20:32:02       38 阅读
  3. C++ :手动实现std::any

    2024-04-09 20:32:02       33 阅读
  4. Vue3有哪些常用的API

    2024-04-09 20:32:02       34 阅读
  5. 怎么使用jwt,token以及redis进行续期?

    2024-04-09 20:32:02       35 阅读
  6. Docker日常系列

    2024-04-09 20:32:02       33 阅读
  7. Vue组合式函数,详细解析

    2024-04-09 20:32:02       35 阅读
  8. 常用的Python内置函数

    2024-04-09 20:32:02       29 阅读