当前位置: 首页 > news >正文

Java阶段四04

第4章-第4节

一、知识点

CSRF、token、JWT

二、目标

  • 理解什么是CSRF攻击以及如何防范

  • 理解什么是token

  • 理解什么是JWT

  • 理解session验证和JWT验证的区别

  • 学会使用JWT

三、内容分析

  • 重点

    • 理解什么是CSRF攻击以及如何防范

    • 理解什么是token

    • 理解什么是JWT

    • 理解session验证和JWT验证的区别

    • 学会使用JWT

  • 难点

    • 理解session验证和JWT验证的区别

    • 学会使用JWT

四、内容

1、CSRF

1.1 概述

CSRF全称为跨站请求伪造(Cross-site request forgery),是一种网络攻击方式,也被称为 one-click attack 或者 session riding。

1.2 原理

CSRF攻击利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。网站是通过cookie来实现登录功能的,而cookie只要存在浏览器中,那么浏览器在访问这个cookie的服务器的时候,就会自动的携带cookie信息到服务器上去。那么这时候就存在一个漏洞了,如果你访问了一个别有用心或病毒网站,这个网站可以在网页源代码中插入js代码,使用js代码给其他服务器发送请求(比如ICBC的转账请求)。那么因为在发送请求的时候,浏览器会自动的把cookie发送给对应的服务器,这时候相应的服务器(比如ICBC网站),就不知道这个请求是伪造的,就被欺骗过去了。从而达到在用户不知情的情况下,给某个服务器发送了一个请求(比如转账)。

 

1.3 解决方案

CSRF攻击的要点就是在向服务器发送请求的时候,相应的cookie会自动的发送给对应的服务器。造成服务器不知道这个请求是用户发起的还是伪造的。这时候,我们可以在用户每次访问有表单的页面的时候,在网页源代码中加一个随机的字符串叫做csrf_token,在cookie中也加入一个相同值的csrf_token字符串。以后给服务器发送请求的时候,必须在body中以及cookie中都携带csrf_token,服务器只有检测到cookie中的csrf_tokenbody中的csrf_token都相同,才认为这个请求是正常的,否则就是伪造的。那么黑客就没办法伪造请求了。

2、JWT

2.1 什么是token

Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。

2.2 什么是JWT

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。

2.3 JWT的请求流程

 

  • 用户使用账号和面发出登录请求

  • 服务器验证并创建一个jwt

  • 服务器返回这个jwt给浏览器

  • 浏览器将该jwt串在请求头中向服务器发送请求

  • 服务器验证该jwt

  • 返回响应的资源给浏览器

2.4 为什么使用JWT
2.4.1 传统Session认证的弊端

在用户首次登录成功后,在服务器存储一份用户登录的信息(session),这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这是传统的基于session认证的过程。

然而,传统的session认证有如下的问题:

  • 每个用户的登录信息都会保存到服务器的session中,随着用户的增多,服务器开销会明显增大

  • 对于非浏览器的客户端、手机移动端等不适用,因为session依赖于cookie,而移动端经常没有cookie

  • 因为session认证本质基于cookie,所以如果cookie被截获,用户很容易收到跨站请求伪造攻击。并且如果浏览器禁用了cookie,这种方式也会失效

  • 由于基于Cookie,而cookie无法跨域,所以session的认证也无法跨域,对单点登录不适用

2.4.2 JWT认证的优势
  • JWT Token数据量小,传输速度也很快

  • 因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持

  • 不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端

  • 单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题

  • 适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端

身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

2.4 JWT结构

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

 

2.5.1 Header

JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256)

2.5.2 Payload

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。

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

2.5.3 Signature

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

3、SpringBoot使用JWT

3.1 添加jwt依赖
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version>
</dependency>
3.2 封装工具类

封装返回值的类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AjaxResult<T> {private Integer code;private String msg;private T data;
​/*** 成功的返回结果** @param msg  成功信息* @param data 返回的值* @param <T>  返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> success(String msg, T data) {return new AjaxResult<T>(200, msg, data);}
​/*** 成功的返回结果** @param data 返回的值* @param <T>  返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> success(T data) {return new AjaxResult<T>(200, "操作成功", data);}
​/*** 失败的返回结果** @param msg  成功信息* @param data 返回的值* @param <T>  返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> error(String msg, T data) {return new AjaxResult<T>(500, msg, data);}
​/*** 失败的返回结果** @param data 返回的值* @param <T>  返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> error(T data) {return new AjaxResult<T>(500, "操作失败", data);}
​/*** 认证失败的返回结果** @param msg  成功信息* @param data 返回的值* @param <T>  返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> unAuth(String msg, T data) {return new AjaxResult<T>(401, msg, data);}
}

将jwt的验证等功能封装一下方便后续调用

public class JWTUtil {// 加密的秘钥封装一下private static final String SECRET = "secret";// id字段private static final String ID_FIELD = "userID";// token的有效时间 30 天private static final Integer TIME_OUT_DAY = 30;
​/*** 创建token** @param user 登陆的用户* @return 返回Token字符串*/public static String createToken(SysUser user) {// 获取日历对象实例Calendar calendar = Calendar.getInstance();// 在当前日期加上 TIME_OUT_DAY 的时间,用于设置过期时间calendar.add(Calendar.DATE, TIME_OUT_DAY);System.out.println(user.getId());// 创建jwtreturn JWT.create()// 可以在token中设置数据,设置一个userId为用户的id// 后续可以直接在token中获取id.withClaim(ID_FIELD, user.getId())// 设置token过期时间.withExpiresAt(calendar.getTime())// Algorithm.HMAC256(SECRET) 使用HMAC256的加密方式// secret 指的是秘钥,在这个秘钥的基础上,进行加密,加大破解的难度这个秘钥爱写什么写什么.sign(Algorithm.HMAC256(SECRET));}
​/*** 验证JWT,返回为false的时候表示验证失败** @param token token字符串* @return 返回boolean 表示是否登录成功*/public static boolean verifyToken(String token) {try {// 验证JWT,验证不通过会报错JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);return true;} catch (Exception e) {return false;}}
​/*** 获取用户id,返回值是0表示没有找到id** @param token token 字符串* @return 返回对应的用户id,如果为0则表示没有用户*/public static Long getUserId(String token) {try {// 获取id,没有id则会报错return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaim(ID_FIELD).asLong();} catch (Exception e) {// 如果报错就返回null表示没有找到对应的用户return 0L;}}
}
​
3.3 token创建测试

写一个登录接口进行测试,控制层、持久层等代码不展示

@PostMapping("/login")
public AjaxResult<String> login(User user) {// 添加用户的帐号密码的条件LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.eq(User::getUsername, user.getUsername());wrapper.eq(User::getPassword, user.getPassword());// 使用Mybatis-Plus查询用户User loginUser = service.getOne(wrapper);// 只有登录成功才需要jwtif (loginUser == null) {return AjaxResult.unAuth("登录失败", null);}String token = JWTUtil.createToken(loginUser);// 登录成功后把token返回给前端return AjaxResult.success(token);
}

发现这个登录接口可以获得到生成的token,说明我们的token的创建是没有问题,那么验证呢?

要验证接口首先要先把请求拦截下来,所以需要添加拦截器

3.4 添加拦截器
3.4.1 拦截器

拦截请求,验证请求头是否携带了token

/*** 授权拦截器,用来验证用户是否有权利访问接口*/
public class AuthInterceptor implements HandlerInterceptor {/*** 要验证用户是否有权限,那么就要验证token** @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从头部获取我们的tokenString token = request.getHeader("token");// 设置返回值类型response.setContentType("text/plain;charset=utf-8");// 如果token是空的就说明没有token,没有权限if (token == null) {response.getWriter().write("没有token");return false;}boolean b = JWTUtil.verifyToken(token);if (!b) {response.getWriter().write("用户认证失败");return false;}// 统一处理用户id不存在的情况Long userId = JWTUtil.getUserId(token);if (userId == null) {response.getWriter().write("用户不存在或者过期");return false;}return b;}
}
​
3.4.2 拦截器配置
@Configuration
public class AuthInterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login");// 登录接口是不要验证token的}
}
3.5 token验证测试
@GetMapping
public AjaxResult<User> getUserInfo(HttpServletRequest req) {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();// 获取TokenString token = req.getHeader("token");// 获取用户IdLong id = JWTUtil.getUserId(token);// 根据Id查询User loginUser = service.getById(id);if (loginUser == null) {return AjaxResult.error("用户不存在", null);}return AjaxResult.success(loginUser);
}
3.6 优化返回值

优化返回值,改成json格式的

3.6.1 封装响应工具类ResponseUtil
public class ResponseUtil {/**** @param response 响应对象* @param data 要返回的对象* @throws IOException*/public static void responseToWeb(HttpServletResponse response, Object data) throws IOException {ObjectMapper mapper = new ObjectMapper();// 使用jackson的对象转JSON字符串String resultStr = mapper.writeValueAsString(data);// 设置返回的数据类型和编码格式response.setContentType("text/plain;charset=utf-8");// 通过写出流发送给调用者response.getWriter().write(resultStr);}
}
3.6.2 直接调用修改即可
if (token == null) {ResponseUtil.responseToWeb(response, AjaxResult.unAuth("没有Token", null));return false;
}

4、小结

本章节中,我们学习了CSRF攻击以及如何防范、理解了什么是token、什么是JWT、学些了session验证和JWT验证的区别、同时在SpringBoot中对JWT进行了封装和使用,对开发中的登录流程有了一个更加清晰的认知。

下一节中,我们将会学习Redis技术,了解什么是NoSql、为什么要使用NoSql、什么是Redis、Redis的优势是什么、如何使用Redis。

相关文章:

Java阶段四04

第4章-第4节 一、知识点 CSRF、token、JWT 二、目标 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验证和JWT验证的区别 学会使用JWT 三、内容分析 重点 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验…...

vivado 时钟指南

时钟指南 每个 FPGA 架构都为时钟提供有专用资源。掌握 FPGA 架构中的时钟资源&#xff0c;使您能够规划好自己的时钟&#xff0c;从而实现时钟 资源的最佳利用。大多数设计无需您了解这些细节。但如果您能够控制布局&#xff0c;同时对每个时钟域上的扇出有良好的思 路&a…...

git项目提交步骤(简洁版)

1.创建仓库 2.填写 信息 3.点击这个按钮 4.找到要上传的文件&#xff0c;在目录内右键点击 5.依次执行命令 在命令窗口中输入&#xff1a;git init 复制仓库地址&#xff1a; 在命令窗口中输入&#xff1a;git remote add origin 仓库地址 在命令窗口中输入&#xff1a;…...

Jmeter-压测时接口如何按照顺序执行

Jmeter-压测时接口如何按照顺序执行-临界部分控制器 在进行压力测试时&#xff0c;需要按照顺序进行压测&#xff0c;比如按照接口1、接口2、接口3、接口4 进行执行 查询结果是很混乱的&#xff0c;如果请求次数少&#xff0c;可能会按照顺序执行&#xff0c;但是随着次数增加…...

模式识别-Ch5-线性判别函数

Ch5 线性判别函数 文章目录 Ch5 线性判别函数引言&#xff1a;生成模型 vs判别模型生成模型 vs 判别模型判别模型分类 线性判别函数与决策面线性判别函数两类情况下的决策多类问题下决策 多类情形-线性机器线性决策面优缺点 广义线性判别函数例&#xff1a;二次判别函数例1: 1-…...

数据结构二叉树-C语言

数据结构二叉树-C语言 1.树1.1树的概念与结构1.2树的相关术语1.3树的表示1.4树形结构实际运用场景 2.二叉树2.1概念与结构2.2特殊的二叉树2.2.1满二叉树2.2.2完全二叉树 2.3二叉树存储结构2.3.1顺序结构2.3.2链式结构 3.实现顺序结构的二叉树4.实现链式结构二叉树4.1前中后序遍…...

字节小米等后端岗位C++面试题

C 基础 引用和指针之间的区别&#xff1f;堆栈和堆中的内存分配有何区别&#xff1f;存在哪些类型的智能指针&#xff1f;unique_ptr 是如何实现的&#xff1f;我们如何强制在 unique_ptr 中仅存在一个对象所有者&#xff1f;shared_ptr 如何工作&#xff1f;对象之间如何同步…...

IOS HTTPS代理抓包工具使用教程

打开抓包软件 在设备列表中选择要抓包的 设备&#xff0c;然后选择功能区域中的 HTTPS代理抓包。根据弹出的提示按照配置文件和设置手机代理。如果是本机则会自动配置&#xff0c;只需要按照提醒操作即可。 iOS 抓包准备 通过 USB 将 iOS 设备连接到电脑&#xff0c;设备需解…...

renben-openstack-使用操作

管理员操作 (1)上传一个qcow2格式的centos7镜像 (2)管理员------>云主机类型------>创建云主机类型 名称&#xff1a;Centos7 VCPU数量&#xff1a;1 内存&#xff1a; 1024 根磁盘&#xff1a; 10G 其他的默认 点击创建云主机类型即可 界面会显示如下 创建公网络 (1)创建…...

HOW - Form 表单确认校验两种模式(以 Modal 场景为例)

目录 一、背景二、具体1. 模式一&#xff1a;点击确认进行校验提示2. 模式二&#xff1a;确认按钮依赖于表单内容实现说明 一、背景 基于react、antd form分别实现如下两种模式&#xff1a; 1、一个 Modal&#xff0c;点击确认进行校验提示2、一个 Modal&#xff0c;确认按钮…...

MATLAB算法实战应用案例精讲-【数模应用】图像边缘检测(附MATLAB和python代码实现)(二)

目录 前言 算法原理 相关概念 二值图像、灰度图像、彩色图像 邻接性、连通性 图像滤波 频率 滤波器 边缘检测算子:Sobel算子、Scharr算子、Laplacian算子、Canny算子 梯度计算 + 顶帽 + 黑帽 + 拉普拉斯金字塔 相位一致性(Phase Congruency,PC) 几种常见的算法…...

高考日语听力中常考2大类关键词

高考日语听力中,有些关键词的出现频率很高,同学们掌握这些关键词的读音和意思,可以提高听力答题的正确率,如时间类、地点类、天气类关键词……本文档为大家整理了干货,高考日语听力常考关键词,帮助同学们区分和积累常用词汇,记得要持续关注哦! 时间类关键词 1.星期 ∙…...

windows和linux的抓包方式

1.实验准备&#xff1a; 一台windows主机&#xff0c;一台linux主机 wireshark使用&#xff1a; 打开wireshark&#xff0c;这些有波动的就代表可以有流量经过该网卡&#xff0c;选择一张有流量经过的网卡 可以看到很多的流量&#xff0c;然后可以使用过滤器来过滤想要的流量…...

工业 4G 路由器赋能远程医疗,守护生命线

在医疗领域&#xff0c;尤其是偏远地区的医疗救治场景中&#xff0c;工业 4G 路由器正发挥着无可替代的关键作用&#xff0c;宛如一条坚韧的 “生命线”&#xff0c;为守护患者健康持续赋能。 偏远地区医疗资源相对匮乏&#xff0c;常常面临着专业医生短缺、诊疗设备有限等困境…...

《太阳之子》Build16524106官方中文学习版

《太阳之子》官方中文版https://pan.xunlei.com/s/VODabFuJ5gA7rCUACMulT5YGA1?pwdc47e# 集战术狙击、解谜与轻度潜行要素于一身&#xff0c;呈现独一无二的第三人称射击游戏体验。每关你只有一发子弹&#xff0c;但你可以进行在命中时重新瞄准、绕过障碍物、加速击穿护甲等操…...

shell-条件判断

目录 一、条件判断 1.按照文件类型进行判断 2.按照文件权限进行判断 3.两个文件之间进行比较 4.两个整数之间进行比较 5.字符串的判断 6.多重条件判断 二、if条件判断 1.单分支if条件语句 2.双分支if条件语句 &#xff08;1&#xff09;判断某文件是否存在 &#x…...

【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集

【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法&#xff0c;以及自动化实时数据采集 mmWave Studio提供的功能完全够用了 不用去纠结用DCA1000低延迟、无GUI传数据 速度最快又保证算力无非就是就是Linux板自己写驱动做串口和UDP 做雷达产品应用也不会采用DCA1000的…...

20250110_ PyTorch中的张量操作

文章目录 前言1、torch.cat 函数2、索引、维度扩展和张量的广播3、切片操作3.1、 encoded_first_node3.2、probs 4、长难代码分析4.1、selected4.1.1、multinomial(1)工作原理&#xff1a; 总结 前言 1、torch.cat 函数 torch.cat 函数将两个张量拼接起来&#xff0c;具体地是…...

【ROS2】☆ launch之Python

☆重点 ROS1和ROS2其中一个很大区别之一就是launch的编写方式。在ROS1中采用xml格式编写launch&#xff0c;而ROS2保留了XML 格式launch&#xff0c;还另外引入了Python和YAML 编写方式。选择哪种编写取决于每位开发人员的爱好&#xff0c;但是ROS2官方推荐使用Python方式编写…...

unity rb.velocity和transform.position

rb.velocity和transform.position是用来控制物体位置的两种方式&#xff0c;前者通常用来控制人物的移动&#xff0c;它们的主要区别和适用场景如下 一&#xff0c;rb.velocity&#xff08;控制刚体的速度&#xff09; 它可以直接控制物体的速度&#xff0c;而不是物体的位置…...

景芯SOC设计实战

终身辅导、一对一辅导&#xff0c;手把手教您完成SoC全流程设计&#xff0c;从入门到进阶&#xff0c;带您掌握SoC芯片架构、算法、设计、验证、DFT、后端及低功耗全流程&#xff01;直播视频不定期升级&#xff01;让您快速超越同龄人&#xff01; 景芯团队主打文档服务器实战…...

【WRF运行报错】总结WRF运行时报错及解决方案(持续更新)

目录 ./real.exe错误1:ERROR while reading namelist physics./wrf.exe错误1:FATAL CALLED FROM FILE: <stdin> LINE: 2419 Warning: too many input landuse types参考./real.exe 错误1:ERROR while reading namelist physics 执行./real.exe时,报错如下: taski…...

Mysql快速列出来所有列信息

文章目录 需求描述实现思路1、如何查表信息2、如何取字段描述信息3、如何将列信息一行展示4、拼接最终结果 需求描述 如何将MySQL数据库中指定表【tb_order】的所有字段都展示出来&#xff0c;以备注中的中文名为列名。 实现思路 最终展示效果&#xff0c;即拼接出可执行执行…...

spring boot发送邮箱,java实现邮箱发送(邮件带附件)3中方式【保姆级教程一,代码直接用】

文章目录 Java发送邮箱的方式1. 基于 Javax.mail 实现关于附件上传的方法 2. 基于 org.apache.commons.mail 实现常见报错 3. 基于 spring-boot-starter-mail 实现&#xff08;推荐&#xff09; 实际开发时需要实现邮件发送&#xff0c;本文章实现如何从零实现邮件发送。也就是…...

数据集-目标检测系列- 电话 测数据集 call_phone >> DataBall

数据集-目标检测系列- 电话 测数据集 call DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” 贵在坚持&#xff01; …...

Zstandard压缩算法

简介 Zstandard(缩写为zstd)是一种开源的无损数据压缩算法,主要设计目标是提供高比率的压缩和快速的解压缩速度。它由Yann Collet开发,并于2015年首次发布。 特点 高比率的压缩(通常比gzip更好)。快速的解压缩速度(通常比gzip更快)。支持流式解压缩。可以选择不同的压…...

npm i 报错

nodejs中 使用npm install命令时报错 npm err! file C: \user\admin\package.json_package.json 里缺少 description 和 repository 两个n字段。-CSDN博客...

【LeetCode】力扣刷题热题100道(26-30题)附源码 轮转数组 乘积 矩阵 螺旋矩阵 旋转图像(C++)

目录 1.轮转数组 2.除自身以外数组的乘积 3.矩阵置零 4.螺旋矩阵 5.旋转图像 1.轮转数组 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 class Solution { public:void rotate(vector<int>& nums, int k) …...

EFCore HasDefaultValueSql

今天小伙伴在代码中遇到了有关 HasDefaultValue 的疑问&#xff0c;这里整理澄清下... 在使用 Entity Framework Core (EFCore) 配置实体时&#xff0c;HasDefaultValue 方法会为数据库列设置一个默认值。该默认值的行为取决于以下条件&#xff1a; 1. 配置 HasDefaultValue 的…...

【数据结构】栈

目录 1.1 什么是栈 1.2 顺序栈 1.2.1 特性 1.3 链式栈 1.3.1 特性 总结&#xff1a; 1.1 什么是栈 栈是只能在一端进行插入和删除操作的线性表(又称为堆栈)&#xff0c;进行插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。 特点&#xff1a;栈是先进后出FILO…...

C++初阶—CC++内存管理

第一章&#xff1a;C/C内存分布 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(si…...

【机器视觉】OpenCV 图像基本变换

文章目录 介绍机器视觉的核心组成部分机器视觉的关键技术和趋势 4. 图像的基本变换4.1 图像的放大与缩小4.2 图像的翻转4.3 图像的旋转4.4 仿射变换之图像平移4.5 仿射变换之获取变换矩阵4.6 透视变换 介绍 机器视觉&#xff08;Machine Vision&#xff09;是一门跨学科的领域…...

【数据库】四、数据库管理与维护

文章目录 四、数据库管理与维护1 安全性管理2 事务概述3 并发控制4 备份与恢复管理 四、数据库管理与维护 1 安全性管理 安全性管理是指保护数据库&#xff0c;以避免非法用户进行窃取数据、篡改数据、删除数据和破坏数据库结构等操作 三个级别认证&#xff1a; 服务器级别…...

徐克版射雕唤醒热血武侠魂,共赴新春侠义之约

2025年大年初一&#xff0c;由徐克执导的古装武侠电影《射雕英雄传&#xff1a;侠之大者》将在影院拉开帷幕&#xff0c;在精彩纷呈的春节档电影中&#xff0c;“大IP”“大导演”“大场面”等标签让这部电影自定档起便备受关注&#xff0c;其精良的制作和传统中国武侠风的设定…...

设计模式(观察者模式)

设计模式&#xff08;观察者模式&#xff09; 第三章 设计模式之观察者模式 观察者模式介绍 观察者模式&#xff08;Observer Design Pattern&#xff09; 也被称为发布订阅模式 。模式定义&#xff1a;在对象之间定义一个一对多的依赖&#xff0c;当一个对象状态改变的时候…...

能量函数和能量守恒

在之前的文章1中讨论了与循环坐标相对应的动量守恒定律和动量矩守恒定律&#xff0c;本文将由拉格朗日方程中导出能量函数&#xff0c;进一步讨论能量守恒定律&#xff0c;并给出耗散系统的处理方法&#xff0c;这其中用到的一个关键数学定理是欧拉定理&#xff08;描述如何将一…...

【pycharm发现找不到python打包工具,且无法下载】

发现找不到python打包工具,且无法下载 解决方法&#xff1a; 第一步&#xff1a;安装distutils&#xff0c;在CMD命令行输入&#xff1a; python -m ensurepip --default-pip第二步&#xff1a;检查和安装setuptools和wheel&#xff1a; python -m pip install --upgrade …...

使用 Maxwell 计算母线的电动势

三相短路事件的动力学 三相短路事件在电气系统中至关重要&#xff0c;因为三相之间的意外连接会导致电流大幅激增。如果管理不当&#xff0c;这些事件可能会造成损坏&#xff0c;因为它们会对电气元件&#xff08;尤其是母线&#xff09;产生极大的力和热效应。 短路时&#x…...

【Python】Python之Selenium基础教程+实战demo:提升你的测试+测试数据构造的效率!

这里写目录标题 什么是Selenium&#xff1f;Selenium基础用法详解环境搭建编写第一个Selenium脚本解析脚本常用的元素定位方法常用的WebDriver方法等待机制 Selenium高级技巧详解页面元素操作处理弹窗和警告框截图和日志记录多窗口和多标签页操作 一个实战的小demo步骤一&#…...

Ubuntu中批量重命名,rename

你可以使用下面的命令批量重命名这些文件&#xff0c;在文件名中插入 _1&#xff1a; 方式一 使用 mv 命令批量重命名 如果你已经在终端中&#xff0c;且当前目录包含这些文件&#xff0c;可以执行以下命令&#xff1a; mv ai.c ai_1.c mv ai.h ai_1.h mv ao.c ao_1.c mv a…...

LINUX 下 NODE 安装与配置

一、官网地址&#xff1a; &#xff08;中文网&#xff09;https://nodejs.cn/ &#xff08;英文网&#xff09;https://nodejs.org/en/ 二、下载安装包 2.1、下载地址&#xff1a;下载 | Node.js 中文网 https://nodejs.cn/download/ 2.2、使用 wget 命令下载到linux 服务器…...

Vue3 el-tree-v2渲染慢的问题

一、现象 使用el-tree-v2处理组织架构权限时&#xff0c;整个树的数据在8500条&#xff0c;勾选数据8200条&#xff0c;打开页面需要8~10秒&#xff0c;用户无法接受。 经调试&#xff0c;发现主要卡在树的渲染回显上&#xff08;勾选数据少时&#xff0c;很快&#xff0c;勾选…...

【redis初阶】浅谈分布式系统

目录 一、常见概念 1.1 基本概念 2.2 评价指标&#xff08;Metric&#xff09; 二、架构演进 2.1 单机架构 2.2 应用数据分离架构 2.3 应用服务集群架构 2.4 读写分离/主从分离架构 2.5 引入缓存 ⸺ 冷热分离架构 2.6 数据库分库分表 2.7 业务拆分 ⸺ 引入微服务 redis学习&…...

模式识别与机器学习 | 十一章 概率图模型基础

隐马尔科夫模型&#xff08;Hidden Markov Model,HMM&#xff09; HMM是建模序列数据的图模型 1、第一个状态节点对应一个初始状态概率分布 2、状态转移矩阵A, 3、发射矩阵概率B 4、对特定的&#xff08;x,y&#xff09;的联合概率可以表示为 α递归计算——前向算法β递归…...

Linux基本指令(1)

一、ls指令 功能&#xff1a;对于目录&#xff0c;显示这个目录下的目录名以及文件名&#xff1b;对于文件&#xff0c;显示文件名 后面可接命令行选项配合使用&#xff0c;接选项时ls与选项以及选项与选项之间要有一个空格&#xff1b; 这里先学习了两个选项&#xff1a;-l…...

逐“绿”前行 企业综合能源管控低碳转型如何推进?

引言&#xff1a; 在“双碳”战略指引下&#xff0c;中国低碳节能各项工作有序推进&#xff0c;逐步建立起碳达峰碳中和“1N”的政策体系&#xff0c;重点领域、重点行业及各地区的碳达峰实施方案相继出台。能源对于促进经济社会发展、增进人民福祉至关重要。近年来&#xff0…...

springboot和vue配置https请求

项目场景&#xff1a; 代码发布到线上使用https请求需要配置ssl证书&#xff0c;前后端都需要修改。 问题描述 如图&#xff0c;我们在调用接口时报如下错误&#xff0c;这就是未配置ssl但是用https请求产生的问题。 解决方案&#xff1a; 前端&#xff1a;在vite.config.js文…...

数据库(2)--建表 表操作

1.建表 语法&#xff1a; create table if not exists 表名( 类型名 类型 comment ‘注释内容’, ... )设置字符集编码与排序规则; create table if not exists student( name char(10) comment 姓名, id bigint comment 学号 )character set utf8mb4 collate utf8mb4_0900_a…...

泷羽sec----学会并玩转powershell【基础1-2】

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…...

2 逻辑符号

在文件和目录的判断或者其他情况中&#xff0c;可以组合使用多个条件。 逻辑与 (&&) 逻辑与运算符 && 用于在多个条件都为真时执行某个操作。 # 判断文件是否存在且可读 if [ -f "$file" ] && [ -r "$file" ]; thenecho "…...