JWT使用教程

目录

  • JWT (JSON Web Token)
    • 1. JWT简介
      • (1) 什么是JWT
      • (2) JWT有什么用
      • (3) JWT认证方式
    • 2. JWT的组成部分
    • 3. 签名的目的
    • 4. JWT与Token的区别
    • 5 JWT的优势
    • 6 JJWT签发与验证token
      • (1) 引入依赖
      • (2) 创建 Token
      • (3) 解析Token
      • (4) 设置过期时间
      • (5) 自定义claims
    • 7. JWT自定义工具类

JWT (JSON Web Token)

1. JWT简介

(1) 什么是JWT

JWT是一种基于 Token 的认证授权机制.
JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。

(2) JWT有什么用

JWT最常见的场景就是授权认证,用户登录之后,后续的每个请求都将包含JWT, 系统在每次处理用户请求之前,都要先进行JWT的安全校验,通过校验之后才能进行接下来的操作。

(3) JWT认证方式

  • JWT通过数字签名的方式,以JSON对象为载体,在用户和服务器之间传递安全可靠的信息.

image.png

  1. 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
  2. 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT(Token)。形成的JWT就是一个形同lll.zzz.xxx的字符串。 token head.payload.singurater
  3. 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。
  4. 前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题) HEADER
  5. 后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。
  6. 验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

2. JWT的组成部分

头部(Header)

  • 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
 {"typ":"JWT","alg":"HS256"}
 
 //typ(Type):令牌类型,也就是 JWT。
 //alg(Algorithm) :签名算法,比如 HS256。

JWT签名算法中,一般有两个选择,一个采用HS256,另外一个就是采用RS256

进行BASE64编码https://base64.us/,编码后的字符串如下:eyJhbGciOiJIUzI1NiJ9

image.png

载荷(payload)

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

 {"sub":"1234567890","name":"John Doe","admin":true}

将上面的JSON数据进行base64编码,得到Jwt第二部分: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

image.png

字段说明,下面的字段都是由 JWT的标准所定义的

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

签名(signature)

服务器通过 Payload、Header 和一个密钥(Secret) 使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

Signature 部分是对前两部分的签名,作用是防止 Token(主要是 payload) 被篡改。

这个签名的生成需要用到:

  • Header + Payload。
  • 存放在服务端的密钥(一定不要泄露出去)。
  • 签名算法。

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

 String encodeString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
 String secret = HMACSHA256(encodeString,secret);

签名用于验证消息在此过程中没有更改,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者是它所说的真实身份。

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

3. 签名的目的

最后一步签名的过程,实际上是对头部以及载荷内容进行签名。

image.png

一般而言,加密算法对于不同的输入产生的输出总是不一样的。对于两个不同的输入,产生同样的输出的概率极其地小(有可能比我成世界首富的概率还小)。所以,我们就把“不一样的输入产生不一样的输出”当做必然事件来看待吧。

所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。

服务器应用在接受到JWT后,会首先对头部和载荷的内容用同一算法再次签名。那么服务器应用是怎么知道我们用的是哪一种算法呢?别忘了,我们在JWT的头部中已经用** alg字段指明了我们的加密算法了。

如果服务器应用对头部和载荷再次以同样方法签名之后发现,自己计算出来的签名和接受到的签名不一样,那么就说明这个Token的内容被别人动过的,我们应该拒绝这个Token,返回一个HTTP 401 Unauthorized响应。

image.png

4. JWT与Token的区别

Token 和 JWT (JSON Web Token) 都是用来在客户端和服务器之间传递身份验证信息的一种方式。但是它们之间有一些区别。

  • Token 是一个通用术词,可以指代任何用来表示身份的字符串。它可以是任何形式的字符串,并不一定是 JWT。
  • JWT 是一种特殊的 Token,它是一个 JSON 对象,被编码成字符串并使用秘密密钥进行签名。JWT 可以用来在身份提供者和服务提供者之间安全地传递身份信息,因为它可以被加密,并且只有拥有秘密密钥的方能解密。

总的来说,JWT 是一种特殊的 Token,它具有更强的安全性和可靠性。

5 JWT的优势

  • 简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快
  • 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
  • 因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持
  • 不需要在服务端保存会话信息,特别适用于分布式微服务。

6 JJWT签发与验证token

使用jjwt实现jwt的签发和解析获取payload中的数据.

JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0)。

官方文档:https://github.com/jwtk/jjwt

(1) 引入依赖

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

(2) 创建 Token

 @SpringBootTest
 class SpringsecurityExampleApplicationTests {
 
     @Test
     void contextLoads() {
     }
 
     @Test
     public void testJJWT(){
 
         JwtBuilder builder = Jwts.builder()
                 .setId("9527")  //设置唯一ID
                 .setSubject("hejiayun_community")   //设置主体
                 .setIssuedAt(new Date())    //设置签约时间
                 .signWith(SignatureAlgorithm.HS256, "mashibing");//设置签名 使用HS256算法,并设置SecretKey
 
         //压缩成String形式,签名的JWT称为JWS
         String jws = builder.compact();
         System.out.println(jws);
         
         /**
          * eyJhbGciOiJIUzI1NiJ9.
          * eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM1ODY2fQ.
          * ybkDJLVj1Fsi8m3agyxtyd0wxv7lHDqCWNOLN-eOxC8
          */
     }
 
 }

运行打印结果:

 eyJhbGciOiJIUzI1NiJ9.
 eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM1ODY2fQ.
 ybkDJLVj1Fsi8m3agyxtyd0wxv7lHDqCWNOLN-eOxC

(3) 解析Token

我们刚才已经创建了token ,在web应用中这个操作是由服务端进行然后发给客户端,客户端在下次向服务端发送请求时需要携带这个token(这就好像是拿着一张门票一样),那服务端接到这个token 应该解析出token中的信息(例如用户id),根据这些信息查询数据库返回相应的结果。

解析JJWS的方法如下:

  1. 使用该 Jwts.parser()方法创建 JwtParserBuilder实例。
  2. setSigningKey() 与builder中签名方法signWith()对应,parser中的此方法拥有与signWith()方法相同的三种参数形式,用于设置JWT的签名key,用户后面对JWT进行解析。
  3. 最后,parseClaimsJws(String)用您的jws调用该方法,生成原始的JWS。
  4. 如果解析或签名验证失败,则整个调用将包装在try / catch块中。
 @Test
 public void parserJWT(){
 
     String JWS = "eyJhbGciOiJIUzI1NiJ9." +
         "eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM1ODY2fQ." +
         "ybkDJLVj1Fsi8m3agyxtyd0wxv7lHDqCWNOLN-eOxC8";
 
     //claims = 载荷 (payload)
 
     try {
         Claims claims = Jwts.parser().setSigningKey("mashibing")
             .parseClaimsJws(JWS)
             .getBody();
         System.out.println(claims);
     } catch (Exception e) {
         System.out.println("Token验证失败! !");
         e.printStackTrace();
     }
 }

运行打印结果:

 {jti=9527, sub=hejiayun_community, iat=1681135866}
 iat: jwt的签发时间
 jti: jwt的唯一身份标识,主要用来作为一次性token。
 sub: jwt所面向的用户

(4) 设置过期时间

有很多时候,我们并不希望签发的token是永久生效的,所以我们可以为token添加一个过期时间。

  • 创建token 并设置过期时间
     @Test
     public void testJJWT2(){
 
         long currentTimeMillis = System.currentTimeMillis();
         Date expTime = new Date(currentTimeMillis);
 
         JwtBuilder builder = Jwts.builder()
                 .setId("9527")  //设置唯一ID
                 .setSubject("hejiayun_community")   //设置主体
                 .setIssuedAt(new Date())    //设置签约时间
                 .setExpiration(expTime)     //设置过期时间
                 .signWith(SignatureAlgorithm.HS256, "mashibing");//设置签名 使用HS256算法,并设置SecretKey
 
         //压缩成String形式,签名的JWT称为JWS
         String jws = builder.compact();
         System.out.println(jws);
 
         /**
          * eyJhbGciOiJIUzI1NiJ9.
          * eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM3MjI0LCJleHAiOjE2ODExMzcyMjR9.
          * evc01MRxLjpbksbMLdVPM9sJGYGhpC3UYOfm4-0sMGE  
          */
     }
  • 解析TOKEN
 打印效果: 异常信息: JWT签名与本地计算的签名不匹配。JWT有效性不能断言,也不应该被信任
 
 Token验证失败! !
 io.jsonwebtoken.MalformedJwtException: JWT strings must contain exactly 2 period characters. Found: 

(5) 自定义claims

我们刚才的例子只是存储了id和subject两个信息,如果你想存储更多的信息(例如角色)可以定义自定义claims。

创建测试类,并设置测试方法:

     @Test
     public void testJJWT3(){
 
         long currentTimeMillis = System.currentTimeMillis()+100000000L;
         Date expTime = new Date(currentTimeMillis);
 
         JwtBuilder builder = Jwts.builder()
                 .setId("9527")  //设置唯一ID
                 .setSubject("hejiayun_community")   //设置主体
                 .setIssuedAt(new Date())    //设置签约时间
                 .setExpiration(expTime)     //设置过期时间
                 .claim("roles","admin")       //设置角色
                 .signWith(SignatureAlgorithm.HS256, "mashibing");//设置签名 使用HS256算法,并设置SecretKey
 
         //压缩成String形式,签名的JWT称为JWS
         String jws = builder.compact();
         System.out.println(jws);
 
         /**
          * eyJhbGciOiJIUzI1NiJ9.
          * eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM3MjI0LCJleHAiOjE2ODExMzcyMjR9.
          * evc01MRxLjpbksbMLdVPM9sJGYGhpC3UYOfm4-0sMGE
          */
     }

解析TOKEN,打印结果

 {jti=9527, sub=hejiayun_community, iat=1681137464, exp=1681237464, roles=admin}

7. JWT自定义工具类

/**
 * JWT工具类
 */
public class JwtUtil {

    //有效期为
    public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000  一个小时
    //设置秘钥明文
    public static final String JWT_KEY = "pan";

    public static String getUUID(){
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        return token;
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据(json格式)
     * @return
     */
    public static String createJWT(String subject) {
        JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间
        return builder.compact();
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据(json格式)
     * @param ttlMillis token超时时间
     * @return
     */
    public static String createJWT(String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间
        return builder.compact();
    }

    private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        SecretKey secretKey = generalKey();
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        if(ttlMillis==null){
            ttlMillis=JwtUtil.JWT_TTL;
        }
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid)              //唯一的ID
                .setSubject(subject)   // 主题  可以是JSON数据
                .setIssuer("sg")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(expDate);
    }

    /**
     * 创建token
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String id, String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间
        return builder.compact();
    }

    public static void main(String[] args) throws Exception {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjYWM2ZDVhZi1mNjVlLTQ0MDAtYjcxMi0zYWEwOGIyOTIwYjQiLCJzdWIiOiJzZyIsImlzcyI6InNnIiwiaWF0IjoxNjM4MTA2NzEyLCJleHAiOjE2MzgxMTAzMTJ9.JVsSbkP94wuczb4QryQbAke3ysBDIL5ou8fWsbt_ebg";
        Claims claims = parseJWT(token);
        System.out.println(claims);
    }

    /**
     * 生成加密后的秘钥 secretKey
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 解析
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot整合SpringSecurity、MyBatis-Plus综合实例:认证、授权

Spring Security 安全框架,系列文章: 《SpringSecurity创建一个简单的自定义表单的认证应用》 《SpringSecurity中的过滤器链与自定义过滤器》 《SpringSecurity实现自定义用户认证方案》 《SpringSecurity密码编码器:使用BCrypt算法加密、自定义密码编码器》 《SpringSecur…

CSDN年度评选揭晓,永洪科技AI技术与智能应用双星闪耀

近日&#xff0c;永洪科技在CSDN&#xff08;中国专业开发者社区&#xff09;的年度评选中&#xff0c;凭借在人工智能技术创新与vividime在行业应用中的卓越表现&#xff0c;一举斩获“人工智能企业”及“智能应用”双料大奖。这一荣誉不仅彰显了永洪科技在AI领域的领先地位&a…

深度学习之“雅可比矩阵与黑塞矩阵”

在深度学习中&#xff0c;导数在优化算法、梯度计算、反向传播等方面起着至关重要的作用。雅可比矩阵&#xff08;Jacobian Matrix&#xff09;和黑塞矩阵&#xff08;Hessian Matrix&#xff09;是多元微积分中的两个重要概念&#xff0c;理解它们的计算方法及应用对掌握深度学…

【MySQL】InnoDB中的Buffer Pool

目录 1、背景2、Buffer Pool【1】含义【2】组成【3】free链表【4】哈希查找缓存页【5】flush链表【6】LRU链表【7】刷新脏页到磁盘【8】Buffer Pool实例【9】chunk【10】Buffer Pool状态信息 3、总结 1、背景 mysql数据是存储在磁盘上的&#xff0c;但是从磁盘上读取数据的速度…

可狱可囚的爬虫系列课程 15:防盗链反爬虫的处理

一、防盗链了解 防盗链是一种技术手段&#xff0c;主要用于防止其他网站通过直接链接的方式使用本网站的资源&#xff08;如图片、文件等&#xff09;&#xff0c;从而节省带宽和服务器资源。当其他网站尝试直接链接到受保护的资源时&#xff0c;服务器会根据设置的规则判断请求…

Dashboard-frps

通过浏览器查看 frp的状态以及代理统计信息展示。 注&#xff1a;Dashboard 尚未针对大量的 proxy 数据展示做优化&#xff0c;如果出现 Dashboard 访问较慢的情况&#xff0c;请不要启用此功能。 需要在 frps.ini中指定 dashboard服务使用的端口&#xff0c;即可开启此功能&…

Element-Plus,使用 El-form中 的 scroll-to-error 没有效果问题记录

因业务需要表单组件中嵌套着表格列表&#xff0c;内容比较多&#xff1b; 所以需要表单校验不通过时&#xff0c;自动定位到不通过的节点&#xff1b; 但发现这个像是没有起到效果一样&#xff0c;后面就是排查的思路了&#xff1a; 容器高度问题&#xff1a;如果表单容器的高度…

实现 Leaflet 多类型点位标记与聚合功能的实战经验分享

在现代的地理信息系统&#xff08;GIS&#xff09;应用中&#xff0c;地图功能是不可或缺的一部分。无论是展示商业网点、旅游景点还是公共服务设施&#xff0c;地图都能以直观的方式呈现数据。然而&#xff0c;当数据量较大时&#xff0c;地图上可能会出现大量的标记点&#x…

次日留存率——mysql计算过程

次日留存率——mysql计算过程 问题&#xff1a;有一张表&#xff0c;有用户id、用户浏览时间a_time&#xff0c;计算每天的用户数、以及次日留存率、三日留存率 创建表user() CREATE TABLE user (id INT, a_time DATE );插入 10 条随机数据 INSERT INTO user (id, a_time) …

老旧android项目编译指南(持续更)

原因 编译了很多项目&#xff0c;找到了一些可观的解决办法 1. android studio里面的jdk版本切换 jdk版本切换在这里&#xff0c;一般安卓开发需要用到4个版本的jdk,jdk8, jdk11, jdk17, jdk21新版的android stuio是默认使用高版本的jdk,所以切换版本是很有必要的 2. 命令…

将VsCode变得顺手好用(1

目录 设置中文 配置调试功能 提效和增强相关插件 主题和图标相关插件 创建js文件 设置中文 打开【拓展】 输入【Chinese】 下载完成后重启Vs即可变为中文 配置调试功能 在随便一个位置新建一个文件夹&#xff0c;用于放置调试文件以及你未来写的代码&#xff0c;随便命名但…

unity学习59: 滑动条 和 滚动条 滚动区域

目录 1 滑动条 slider 1.1 创建slider 1.2 构成的子物体 1.2.1 找到 某个UI的 方法 1.3 构成的component&#xff0c;主体就是 slider 2 核心属性 2.1 value 2.2 direction 3 作用 3.1 由于是fill back 可以实现血条效果 3.2 可以取得 slider.value 数值 1 滑动条…

【问题记录】Go项目Docker中的consul访问主机8080端口被拒绝

【问题记录】Go项目Docker中的consul访问主机8080端口被拒绝 问题展示解决办法 问题展示 在使用docker中的consul服务的时候&#xff0c;通过命令行注册相应的服务&#xff08;比如cloudwego项目的demo_proto以及user服务&#xff09;失败。 解决办法 经过分析&#xff0c;是…

Hadoop第2课(伪分布式集群的搭建)

jdk和hadoop安装包&#xff1a; hadoop-2.9.2.t......等2个文件官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 1、用XFTP发送hadoop安装包和jdk到/home/hadoop/目录下&#xff08;hadoop用户的主目录&#xff09; 2、解压jdk安装包到~目录 卸载jdk的命令&#xff1a;r…

【前端基础】Day 3 CSS-2

目录 1. Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 2. CSS的复合选择器 2.1 后代选择器 2.2 子选择器 2.3 并集选择器 2.4 伪类选择器 2.4.1 链接伪类选择器 2.4.2 focus伪类选择器 2.5 复合选择器总结 3. CSS的元素显示模式 3.1 什么是元素显示…

微信小程序源码逆向 MacOS

前言 日常工作中经常会遇到对小程序的渗透测试&#xff0c;微信小程序的源码是保存在用户客户端本地&#xff0c;在渗透的过程中我们需要提取小程序的源码进行问题分析&#xff0c;本篇介绍如何在苹果电脑 MacOS 系统上提取微信小程序的源码。 0x01 微信小程序提取 在苹果电…

C语言入门资料分享源码+PDF速查手册

01 目标&#xff1a;掌握基础语法&#xff0c;能编写简单的程序 源码PDF获取 通过网盘分享的文件&#xff1a;C语言入门到精通.rar 链接: https://pan.baidu.com/s/1lcKj3aywRJUecLmoDeQfFg?pwdxiyx 提取码: xiyx 02 环境搭建 安装编译器&#xff08;推荐GCC/MinGW/M…

深入理解Java反射机制:从基础到高级应用

一、反射机制概述 Java 反射机制是 Java 语言的一个重要特性&#xff0c;它允许程序在运行时动态地获取类的信息&#xff0c;以及动态地调用对象的方法、修改属性等操作。这意味着程序员可以在运行期间检查和操作类、对象的各种元素&#xff0c;而不需要在编译时就知道这些信息…

[VMware]卸载VMware虚拟机和Linux系统ubuntu(自记录版)

记录一下,不是教程,只是防止我做错了可以回溯一下 我打开vscode,就会跳出下图 虚拟机,Linux还是很久之前学习安装的,种途可能卸载过(不太记得了),现在尝试彻底卸载 彻底卸载VMware虚拟机的详细步骤-CSDN博客虚拟机Vmware 转移 克隆 卸载及移除Linux系统_克隆的虚拟机怎么移除-…

server.servlet.session.timeout: 12h(HTTP 会话的超时时间为 12 小时)

从你提供的配置文件&#xff08;应该是 Spring Boot 的 application.yml 或 application.properties 文件&#xff09;来看&#xff0c;以下部分与会话超时时间相关&#xff1a; server:servlet:session:timeout: 12h # timeout: 30cookie:name: VENDER_SID会话超时时间的…