JWT -- 复盘

1、前言

1.1、Token流程

        先来回顾一下利用 token 进行用户身份验证的流程:

  1. 客户端使用用户名和密码请求登录
  2. 服务端收到请求,验证用户名和密码
  3. 验证成功后,服务端会签发一个 token再把这个 token 返回给客户端
  4. 客户端收到 token 后可以把它存储起来,比如放到 cookie 中
  5. 客户端每次向服务端请求资源时需要携带服务端签发的 token,可以在 cookie 或者 header 中携带
  6. 服务端收到请求,然后去验证客户端请求里面带着的 token,如果验证成功,就向客户端返回请求数据

单点登录:一次登录多处使用

        前提:单点登录多使用在分布式系统中

京东:单点登录,是将 token 放入到 cookie 中
案例:将浏览器的 cookie 禁用,则在登录京东则失效,无论如何登录不了

1.2、Token的优点

        基于token的认证方式相比传统的session认证方式更节约服务器资源,并且对移动端和分布式更加友好。其优点如下:

  1. 支持跨域访问:cookie 默认是不支持跨域的,而将 token 放在 HTTP 请求头中可以有效支持跨域请求。这是因为 HTTP 头是可以自定义的,而且标准的跨域资源共享(CORS)策略允许指定哪些头信息可以跨域传输。

  2. 无状态:Token 是无状态的,存储了所有必要的用户信息。这使得后端服务可以不存储状态信息,从而使架构更简单,更易于扩展。这种方式尤其适用于分布式系统和微服务架构,其中各个服务需要轻量级并独立处理请求。

  3. 更适用CDN:使用 token 认证的无状态特性意味着请求可以由任何服务器处理,包括通过 CDN 分发的服务器。这样可以减少对原始服务器的直接请求,提高响应速度并降低延迟。

  4. 更适用于移动端:在非浏览器环境,如移动应用或桌面应用中,cookie 支持可能有限或不稳定,使用 token 可以简化认证过程,因为开发者可以更灵活地控制如何存储和传输 token(例如存储在本地存储或内存中)。

  5. 无需考虑CSRF:由于 token 通常不会自动随请求发送,与 cookie 不同,它需要显式地附加到 HTTP 请求的头部。这种特性意味着不会自动发送到创建它们的同一域,因此大大降低了 CSRF 攻击的风险。

而JWT就是上述流程当中token的一种具体实现方式,其全称是 JSON Web Token

 1.3、JWT Token 

       JWT(JSON Web Tokens)的本质是一个字符串,它通过一定的方式对用户信息进行封装、编码和安全处理。下面我会用一个更加生活化的比喻来解释JWT的工作原理和特性:

        想象JWT是一封信件。信封上写着寄信人(头部Header),信的内容是关于寄信人的某些信息(载荷Payload),比如姓名、权限等。为了确保这封信在送达时内容没有被篡改,寄信人在信封上封了一层蜡,并在蜡上压上了自己的印章(签名Signature)。这样,收信人收到信后,只需检查印章是否完整,就能确定信件是否在途中被人篡改过。

在技术层面:

  1. 头部(Header):包含了使用的加密算法与令牌的类型,类似于“信封”的标识。
  2. 载荷(Payload):包含了要传输的信息,这些信息被称为“声明”(Claims),可以包含用户的身份信息以及其他任何需要的数据。
  3. 签名(Signature):服务器利用一个密钥对头部和载荷进行加密,加密后的字符串就是“印章”,用以确保数据在传输过程中未被篡改。

        当JWT在用户和服务器之间传递时,服务器可以通过检查签名来验证信息是否被篡改,以及用户的合法性。这个机制使得JWT非常适合用于身份验证与信息交换,而且由于JWT的自包含性,服务器无需连接数据库即可完成验证,提高了处理速度和减少了系统开销。

JWT的认证流程如下:

1、前端通过Web表单将自己的用户名和密码发送到后端的接口,这个过程一般是一个POST请求。建议的方式是通过SSL加密的传输(HTTPS),从而避免敏感信息被嗅探。

2、后端核对用户名和密码成功后,将包含用户信息的数据作为JWT的Payload,将其与JWT Header分别进行Base64编码拼接后签名,形成一个 JWT Token形成的JWT Token就是一个如同lll.zzz.xxx的字符串

3、后端将JWT Token字符串作为登录成功的结果返回给前端。前端可以将返回的结果保存在浏览器中,退出登录时删除保存的 JWT Token 即可

4、前端在每次请求时将JWT Token放入HTTP请求头中的Authorization属性中(解决XSS和XSRF问题)

5、后端检查前端传过来的JWT Token,验证其有效性,比如检查签名是否正确、是否过期、token的接收方是否是自己等等

6、验证通过后,后端解析出JWT Token中包含的用户信息,进行其他逻辑操作(一般是根据用户信息得到权限等),返回结果

 

二、为什么要使用JWT

2.1、传统Session认证的弊端

1、用户认证的初次请求

  1. 用户提交认证信息:用户在客户端(如Web浏览器)输入用户名和密码,然后提交这些信息到服务器进行认证。

  2. 服务器处理认证:服务器接收到用户名和密码后,验证这些信息。如果认证成功,服务器需要创建一个会话来跟踪用户的状态,因为HTTP本身不会记住用户的状态或身份。

2、会话创建和会话ID的分发

  1. 创建会话和会话ID:认证成功后,服务器创建一个session,这个session包含有关用户的信息,如用户ID、权限等。每个session都会被分配一个唯一的session ID。

  2. 发送会话ID至客户端:一旦session创建,服务器通过HTTP响应将session ID作为cookie发送给用户的浏览器。服务器通过设置响应头中的Set-Cookie来实现这一点,cookie中会包含session ID。

3、客户端存储和后续请求

  1. 客户端存储Cookie:用户的浏览器接收到这个cookie后,将其保存在本地。此后,每当浏览器向服务器发送请求时,它会自动在请求头中包含这个cookie。

  2. 服务器识别并处理请求:服务器每次接收请求时,会首先检查请求头中是否包含有效的session ID。服务器通过session ID查找相应的session对象,如果找到,就可以识别用户并获取用户的登录状态和其他相关信息。

4、维护用户会话状态

  1. 会话状态的持续性:通过这种方式,即使HTTP协议是无状态的,服务器也能“记住”用户在多个请求之间的状态。这意味着用户在浏览不同页面或进行不同操作时无需重复登录。

5、会话结束

  1. 结束会话:当用户选择登出或者session过期时(由服务器决定何时过期),服务器将终止session,并可能要求浏览器删除包含session ID的cookie。

        通过这种机制,session认证允许Web应用跟踪用户的状态和身份,提供连贯的用户体验。然而,正如先前讨论的,这种方法在处理分布式系统、大量用户、移动应用或跨域请求时可能会面临一些挑战和限制。

        这就是为什么在许多现代应用中,特别是需要弹性扩展和微服务架构的场景中,越来越倾向于使用基于token的认证方式,如JWT。

通过一个生活中例子来类比传统基于session的认证过程:

        想象你去一个大型音乐会,入场时你需要出示购票凭证(这就像是用户在网站上输入用户名和密码)。一旦检票员验证了你的票是有效的,他们会在你的手腕上贴一个不易脱落的贴纸或戴上手环(这相当于服务器为用户创建session并发放一个session ID)。

        一旦你有了这个手环,你就可以自由地进出会场的不同区域,不需要每次进入新区域都重新出示你的购票凭证。只要你的手上戴着那个手环,工作人员就可以通过看手环确认你的入场资格(这就像Web服务器通过检查cookie中的session ID来确认用户的身份和状态)。

        每当你离开音乐会场地时,你可能会被要求剪掉手环,这表示你的访问权限已经结束,再次进入需要重新购买门票或验证(这与用户登出或session过期后服务器终止session相似)。

        这个例子生动地说明了session的工作原理:一次验证,多次使用,直到会话结束。同样地,在Web环境中,用户通过一次登录验证后,可以在不需要重新验证的情况下访问多个页面和服务,直到session结束。

 2.2、传统的session认证的问题

1. 服务器资源消耗大

        每个用户登录后,服务器都必须为其创建并维护一个session。这些session信息通常存储在服务器的内存中。随着在线用户数量的增加,这将显著增加服务器的内存消耗。在用户规模较大的系统中,这会导致显著的性能瓶颈和成本增加。

2. 不利于分布式系统

        在现代的云基础设施和微服务架构中,应用通常被部署在多个服务器或容器上以实现负载均衡和高可用性。由于session默认存储在一个服务器上,用户的后续请求若路由到不同的服务器,其session信息将不可用,除非通过集中式的session管理,如使用Redis等。这不仅增加了架构的复杂性,还可能引入新的性能瓶颈。

3. 移动端兼容性差

        移动设备上的应用可能不支持cookie,或者对cookie的处理方式与桌面浏览器不同。这使得基于cookie的session认证方法在移动端应用中不那么有效,尤其是在原生应用中。

4. 安全隐患

        Session认证依赖于cookie来存储session ID,如果cookie被截获(例如通过XSS攻击或者用户在不安全的网络环境中使用应用),攻击者可以利用这些信息冒充用户。此外,基于cookie的机制也容易受到CSRF攻击,尽管可以通过其他措施(如使用CSRF token)来缓解这一问题。

5. 前后端分离的挑战

        在前后端分离的架构中,前端通常通过API与后端通信。每次API请求都需要携带用户的身份信息。由于cookie和session信息需要在多个中间件之间传递,这增加了维护和调试的复杂性,特别是在跨域场景下。

6. 跨域问题

        基于cookie的session无法轻松处理跨域请求,因为浏览器出于安全考虑默认不会发送cookie到其他域。这限制了基于session的应用在单点登录和跨服务集成中的能力。

2.3、JWT认证的优势

1. 简洁和高效

        JWT是一种非常紧凑的令牌格式。因为它只是一个由三部分组成的字符串——头部(Header)、载荷(Payload)和签名(Signature),每部分之间通过点(.)分隔。由于其紧凑的格式,JWT在网络中的传输效率非常高,适用于各种网络环境,尤其是带宽有限的情况。

2. 跨平台和跨语言支持

        JWT基于JSON格式,这使得它非常容易在不同的编程语言和平台中处理。几乎所有现代编程语言都支持JSON解析和生成,这样JWT可以轻松地在各种客户端和服务器端技术之间使用,无论是Web、桌面还是移动应用。

3. 无状态和适用于分布式微服务

        JWT不需要在服务器端存储会话状态,因此它是无状态的。这一特性非常适合分布式系统和微服务架构,因为服务间的通信不需要每次都进行复杂的会话同步。每个服务只需要能够验证JWT的签名并解析其内容,就可以独立进行身份验证,大大简化了系统架构。

4. 单点登录友好

        JWT非常适合实现单点登录(SSO),因为它可以生成一次并由多个不同的系统验证。由于JWT不依赖于cookie,它可以通过前端存储(如LocalStorage或SessionStorage)在客户端进行管理,也可以作为URL参数安全地在不同应用间传递,这使得跨域身份验证成为可能。

5. 适合移动端应用

        在移动应用中,使用基于cookie的session认证往往不是最佳选择,因为移动平台对cookie的支持不如Web浏览器。JWT则可以在应用内部安全存储,如在设备的本地存储中,或者每次请求时通过HTTP头部发送,这使得它非常适合移动设备和原生应用。

三、JWT结构 

其实是上面为什么使用JWT也有提到的它的结构  -->(标头(Header)、有效载荷(Payload)和签名(Signature))

        确实,JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串。
 

3.1、Header

        JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

{

    "alg": "HS256", // 指明签名使用的哈希算法,通常是HMAC SHA256或RSA。

    "typ": "JWT" //表示令牌的类型,标准中规定为“JWT”

}

3.2、Payload

        有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择

iss:发行人

exp:到期时间

sub:主题

aud:用户

nbf:在此之前不可用

iat:发布时间

jti:JWT ID用于标识该JWT

        除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中,如下例:

{

    "sub": "1234567890",

    "name": "zNuyoah",

    "admin": true

}

        注意:默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。

        JWT只是适合在网络中传输一些非敏感的信息。

3.3、Signature

        签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名

HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

        总结:JWT由 Header加密.Payload加密.(Header加密.Payload加密)再加密三部分组成

        注意:JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:
        1、header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据。
        2、signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。

        注意:secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值。

四、总结

4.1、什么是JWT

        JSON Web Token,通过数字签名的方式,以JSON对象为载体,在不同的服务终端之间安全的传输信息。

4.2、JWT有什么用

        JWT最常用的场景就是授权认证,一旦用户登录,后续每个请求都将包含JWT,系统每次处理用户请求之前,都要进行JWT安全校验,通过之后再进行处理

4.3、JWT组成

        JWT由三部分组成,用 . 拼接

1.Header

{

    "alg": "HS256",

    "typ": "JWT"

}

2.Payload

{

    "sub": "1234567890",

    "name": "zNuyoah",

    "admin": true

}

3.Signature

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var Signature = HMACSHA256(encodedString, 'secret');

 五、简单代码演示

1、POM

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

2、测试 - 加密(重新生成的都不一样的,因为里面包含超时时间,每次执行的时间都不是同一时刻)

 

@Test
public void test() {
    JwtBuilder builder = Jwts.builder();
    String jwtToken = builder
            // header
            .setHeaderParam("typ", "JWT")
            .setHeaderParam("alg", "HS256")
            // payload
            .claim("username", "zNuyoah")
            .claim("role", "admin")
            // 设置主题
            .setSubject("admin-test")
            // 设置过期时间 - 一天
            .setExpiration(new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 24)))
            .setId(UUID.randomUUID().toString())
            // signature
            .signWith(SignatureAlgorithm.HS256, "admin")
            .compact();

    System.out.println(jwtToken);
}

3、测试 - 解密

@Test
public void parse() {
    String token = "*************"; 
    JwtParser parser = Jwts.parser();
    Jws<Claims> claimsJws = parser.setSigningKey("admin").parseClaimsJws(token);

    Claims claims = claimsJws.getBody();
    System.out.println(claims.get("username"));     // zNuyoah
    System.out.println(claims.get("role"));         // admin
    System.out.println(claims.getId());             
    System.out.println(claims.getSubject());        // admin-test
    System.out.println(claims.getExpiration());     
}

 六、实际开发应用

        在Spring Boot项目中,结合JWT和Redis进行用户身份验证和会话管理是一种非常高效和安全的做法。

步骤 1: 生成并存储会话信息

        在用户成功登录后,服务器生成一个随机的Token(如使用UUID)。这个Token作为用户会话的唯一标识,并将其与用户的详细信息一起存入Redis中。这里,Redis起到了存储用户会话状态的作用,有效地替代了传统的session机制。设置适当的过期时间后,这个Token将在一定时间后自动失效,保障了安全性。

实现提示:

  • 使用UUID.randomUUID().toString()生成随机Token。
  • 使用Spring Data Redis或Jedis等库将Token和用户信息存储在Redis中。
  • 设置Token的过期时间以控制会话有效期。

步骤 2: 生成JWT

        将步骤1中生成的Token放入JWT的payload中,然后生成JWT。这个JWT将作为用户的身份凭证,传送给前端。

实现提示:

  • 在JWT的payload中加入Token作为自定义声明(claim),例如
  • { "token": "<random_token>" }
  • 使用库如jjwtjava-jwt来生成JWT。
  • 确保选择合适的加密算法和秘钥保护JWT的完整性和安全性。

步骤 3: 前端存储及传输JWT

        前端在收到JWT后,通常会存储在本地存储(如localStorage或sessionStorage)中。每次发送请求到服务器时,将JWT添加到HTTP请求的Authorization头部中,通常采用Bearer <token>格式。

实现提示:

  • 确保前端在发送请求时正确地设置Authorization头部。
  • 前端应该处理JWT过期或无效的情况,可能需要重新登录或刷新Token。

步骤 4: 后端验证JWT和会话

        后端需要验证每个请求中的JWT的合法性。这包括解析JWT,验证签名,检查Token有效性等。验证通过后,从JWT解析出随机Token,并使用它从Redis中查询用户信息。

实现提示:

  • 实现一个Spring Security的过滤器或者使用@RestControllerAdvice来处理所有进入的请求,从中解析和验证JWT。
  • 如果Redis中可以查询到与Token对应的用户信息,则认为用户已经登录,继续处理请求;如果查不到,返回错误响应,如401 Unauthorized。
  • 考虑JWT或Token在Redis中过期的情况,合理处理这些异常情况。
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String JWT = request.getHeader("Authorization");
        try {
            // 1.校验JWT字符串
            DecodedJWT decodedJWT = JWTUtils.decode(JWT);
            // 2.取出JWT字符串载荷中的随机token,从Redis中获取用户信息
            ...
            return true;
        }catch (SignatureVerificationException e){
            System.out.println("无效签名");
            e.printStackTrace();
        }catch (TokenExpiredException e){
            System.out.println("token已经过期");
            e.printStackTrace();
        }catch (AlgorithmMismatchException e){
            System.out.println("算法不一致");
            e.printStackTrace();
        }catch (Exception e){
            System.out.println("token无效");
            e.printStackTrace();
        }
        return false;
    }
}

 七、小记

        在实际开发中需要用下列手段来增加JWT的安全性:

1. 使用HTTPS传输

        使用HTTPS可以有效防止中间人攻击(MITM),这种攻击方式包括但不限于网络监听和数据劫持。HTTPS通过对所有传输数据进行加密,确保数据在传输过程中的机密性和完整性。即使数据被拦截,攻击者也无法直接读取或篡改加密的内容。

实施方法:

  • 在服务器配置SSL/TLS证书,强制使用HTTPS连接。
  • 确保所有API端点只通过HTTPS提供服务。
  • 配置HTTP严格传输安全(HSTS)来防止SSL剥离攻击。

2. 保证服务器的安全

        服务器的安全是保护JWT安全的关键,因为JWT的签名密钥必须保持绝对的安全。如果服务器被攻破,攻击者可能获得签名密钥,从而可以伪造有效的JWT。

实施方法:

  • 定期更新和打补丁操作系统和应用软件。
  • 使用防火墙、入侵检测系统(IDS)和入侵防御系统(IPS)来防护服务器。
  • 对服务器进行安全配置,限制不必要的服务和访问。
  • 定期进行安全审计和渗透测试。

3. 定期更换哈希签名密钥

        定期更换密钥可以降低密钥被破解的风险。如果密钥泄露或者被破解,定期更换密钥可以限制攻击者使用旧密钥造成的损害。

实施方法:

  • 设计一个密钥轮换计划,例如每三个月更换一次密钥。
  • 确保密钥更换过程中,旧密钥和新密钥在一段时间内共存,以确保在过渡期间不会因密钥更新而影响用户体验。
  • 使用密钥管理系统来保护和管理密钥,确保密钥的安全性和更换的自动化。

4. 增加JWT的复杂性和安全性

        除了上述措施,还可以通过增加JWT自身的复杂性和安全性来提高整体的安全水平。

实施方法:

  • 使用较长的密钥长度,比如使用256位以上的密钥,以提高破解的难度。
  • 对于非常敏感的应用,可以考虑对JWT的payload部分进行加密。
  • 限制JWT的有效期,设置较短的过期时间,减少JWT被滥用的风险。

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

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

相关文章

Linux进程(一) -- 介绍进程

计算机的系统架构 用户部分 这是用户直接与计算机交互的部分&#xff0c;包括以下三种操作&#xff1a; 指令操作&#xff1a;用户通过命令行界面&#xff08;CLI&#xff09;输入指令来操作计算机。开发操作&#xff1a;开发人员编写和调试程序代码&#xff0c;与计算机系统…

[AWS] stepfunctions-local

本质是本地docker,只支持异步调用 run aws-stepfunctions-localdocker run -p 8083:8083 \ --mount type=bind,readonly,source=/path/MockConfigFile.json,destination=/home/StepFunctionsLocal/MockConfigFile.json \ -e SFN_MOCK_CONFIG="/home/StepFunctionsLocal/…

照明灯具十大排名都有哪些?市面上比较流行的十大护眼台灯品牌推荐

照明灯具十大排名都有哪些&#xff1f;护眼台灯排名当中靠前的主要有书客、飞利浦、松下等品牌。照明灯具作为家居与办公环境中不可或缺的元素&#xff0c;其品质与选择直接关系到人们的视觉健康与舒适度。本文将为大家揭示照明灯具的十大排名&#xff0c;让大家了解市场上最受…

【科学研究】 女性主义:网络中的性别歧视现象

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

识别AI论文生成内容,降低论文高AI率

AI写作工具能帮我们在短时间内高效生成一篇毕业论文、开通报告、文献综述、任务书、调研报告、期刊论文、课程论文等等&#xff0c;导致许多人开始使用AI写作工具作为撰写学术论文的辅助手段。而学术界为了杜绝此行为&#xff0c;开始使用AIGC检测系统来判断文章是由AI生成还是…

TL(TypeLetters)功能扩展#002:解放CPU。带打字练习软件原理分析

TL&#xff08;TypeLetters&#xff09;功能扩展#002&#xff1a; 解放CPU&#xff0c;带打字练习软件原理分析。 今天Type Letters时发现一个问题&#xff0c;TL的CPU占用达到了14%&#xff0c;按说一个小小的打字练习软件&#xff0c;不会有这么高的CPU占用率&#xff0c;是什…

「Qt Widget中文示例指南」如何实现一个快捷编辑器(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 快捷编辑器示例展示…

1U机架式多卡聚合设备在视频指挥车上的应用解决方案

随着信息技术的飞速发展&#xff0c;视频指挥车作为现代化指挥系统的重要组成部分&#xff0c;在各类应急指挥调度中发挥着越来越重要的作用。而1U机架式多卡聚合设备&#xff0c;以其高带宽、高可用性和高稳定性的特点&#xff0c;成为视频指挥车中不可或缺的关键设备。本文将…

Softing工业新版dataFEED OPC Suite支持访问SINUMERIK 840D数控机床

2024年4月17日&#xff08;哈尔&#xff09;&#xff0c;Softing工业自动化宣布发布dataFEED OPC Suite V5.35新版。该版本支持访问SINUMERIK 840D数控机床数据&#xff0c;并集成了Web服务功能。 &#xff08;dataFEED OPC Suite V5.35支持访问SINUMERIK 840D数控机床&#xf…

腾讯云服务器部署前后端服务

服务器&#xff1a;OpenCloudOS &#xff08;兼容centos8&#xff09; 后端&#xff1a;javaSpringboot 前端&#xff1a;Vue 下载jdk 1&#xff09;下载jdk11 wget https://download.java.net/openjdk/jdk11/ri/openjdk-1128_linux-x64_bin.tar.gz 2&#xff09;解压jdk …

基于微信小程序+JAVA Springboot 实现的【停车场小程序】app+后台管理系统 (内附设计LW + PPT+ 源码+ 演示视频 下载)

项目名称 项目名称&#xff1a; 停车场微信小程序的设计与实现 在当前信息技术飞速发展的背景下&#xff0c;停车场微信小程序的开发成为了一个创新的解决方案&#xff0c;旨在提高停车场管理的效率和用户的停车体验。本项目通过深入分析现有停车场管理系统的不足&#xff0c…

硬件FMEA与软件FMEA的区别——FMEA软件

​免费试用FMEA软件-免费版-SunFMEA 在产品开发和制造过程中&#xff0c;失效模式与影响分析&#xff08;FMEA&#xff09;作为一种预防性的质量工具&#xff0c;对于确保产品性能和质量至关重要。然而&#xff0c;硬件FMEA和软件FMEA在应用和实践方面存在显著的区别。本文旨在…

第51期|GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

双星号(**)和单星号(*)在Python参数传递中的妙用

在Python中&#xff0c;参数传递是一个非常重要的概念&#xff0c;它允许函数接收任意数量的参数。而双星号(**)和单星号(*)在参数传递中扮演着关键角色。本文将详细讲解这两个符号的用法&#xff0c;并通过示例代码帮助初学者理解它们的工作原理。 单星号(*) 单星号(*)用于函…

华为配置带反射器的iNOF功能实验

配置带反射器的iNOF功能示例 适用产品和版本 安装了SAN系列单板的CE16800系列交换机V300R020C10或更高版本。 安装了P系列单板的CE16800系列交换机V300R021C00或更高版本。 CE6866、CE6866K、CE8851-32CQ8DQ-P、CE8851K系列交换机V300R020C00或更高版本。 CE6860-SAN、CE8850-S…

MyBatis——动态 SQL

一、if 标签 <mapper namespace"com.powernode.mybatis.mapper.CarMapper"><select id"selectByMultiCondition" resultType"car">select * from t_car where<if test"brand ! null and brand ! ">brand like #{br…

【Docker】docker 镜像如何push到私有docker仓库

文章目录 一、 网址解析对于Linux和macOS系统&#xff1a;对于Windows系统&#xff1a; 二、 镜像push 一、 网址解析 希望 registry.meizu.com 能够解析到内网IP地址&#xff08;例如10.128.17.157&#xff09;&#xff0c;您可以通过修改主机的 hosts 文件来实现。 hosts 文…

百度文心一言 java 支持流式输出,Springboot+ sse的demo

参考&#xff1a;GitHub - mmciel/wenxin-api-java: 百度文心一言Java库&#xff0c;支持问答和对话&#xff0c;支持流式输出和同步输出。提供SpringBoot调用样例。提供拓展能力。 1、依赖 <dependency> <groupId>com.baidu.aip</groupId> <artifactId…

7天精通Web APIs——正则阶段案例(理论+实战)(第六天)

正则表达式的定义和使用 定义&#xff1a;是一种匹配模式&#xff0c;用于匹配字符串中字符组合 作用&#xff1a;表单验证&#xff08;匹配&#xff09;、过滤敏感词&#xff08;替换&#xff09;、字符串中提取我们想要的部分&#xff08;提取&#xff09; 使用分为两步&…

基于C#开发web网页管理系统模板流程-登录界面

前言&#xff0c;首先介绍一下本项目将要实现的功能 &#xff08;一&#xff09;登录界面 实现一个不算特别美观的登录窗口&#xff0c;当然这一步跟开发者本身的设计美学相关&#xff0c;像蒟蒻博主就没啥艺术细胞&#xff0c;勉强能用能看就行…… &#xff08;二&#xff09…