Spring Security 认证流程,长话简说

一、代码先行

1、设计模式

SpringSecurity 采用的是 责任链 的设计模式,是一堆过滤器链的组合,它有一条很长的过滤器链。

不过我们不需要去仔细了解每一个过滤器的含义和用法,只需要搞定以下几个问题即可:怎么登录、怎么校验账户、认证失败处理。

2、 POM依赖

没啥好说的,maven导入即可。
不写版本号,默认就会下载 最新的 版本。

<!--springSecurity-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency> 

3、登录

不管你用哪种权限框架,第一个要解决的问题就是登录。就是在我们的登录接口中,将账户密码委托给权限框架接管,让权限框架帮我们做校验和权限认证。

新建一个登录方法,目的是 验证用户的 用户名密码,并在验证成功后为该用户生成一个JWT。

@GetMapping("/login")
public String securityLogin(String username,String password){UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username,password);// 使用authenticationManager调用loadUserByUsername获取数据库中的用户信息,Authentication authentication = authenticationManager.authenticate(authToken);if(authentication == null) {throw new RuntimeException("登录失败啦呀");}//获取符合security规范的UserSecurityUser securityUser = (SecurityUser) authentication.getPrincipal();String token = jwtUtil.createToken(securityUser.getUser());return token;
}

UsernamePasswordAuthenticationToken就是 我们委托 框架 帮我们托管 的 登录凭证

然后是:

单词重点说明: authenticate (v) 证明…是事实; authentication (n)证明

Authentication authentication = authenticationManager.authenticate(authToken);   

这就是spring security帮我们 执行 认证授权 的方法,最终返回一个 认证结果

大家思考一下,正常登录的逻辑无非是 4步走:

  1. 输入账号密码
  2. 根据账号从 DB数据库 中获取用户实体
  3. 校验密码是否正确
  4. 校验成功,将用户生成token后返回

我们再回过来看 上面的代码,第2步和第3步没见到。
肯定是spring security已经帮我们做了,但是,这并不代表我们可以省略这两步,只是需要我们写在别的地方,仅此而已。

4、根据账号从DB中获取用户实体

这个步骤是不可能不写的,只是写到了别处。
说明一点,spring security中的 用户概念,有自己的一套规则,不能直接用 我们系统里面的 User类。

因此如果我们要用spring security,就得 实现 他的 用户接口UserDetails
所以,我们新建一个SecurityUser类:

@Data
@NoArgsConstructor
public class SecurityUser implements UserDetails {// 使用聚合模式,将我们自己的User对象聚合到SecurityUser中// user字段存储了用户的一些信息,例如用户名和密码等private User user;// 覆盖UserDetails接口中的getAuthorities方法,返回用户的权限集合// 这里返回null,表示未实现获取权限的逻辑@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}// 覆盖UserDetails接口中的getPassword方法,返回用户的密码// 这里通过调用user对象的getPwd方法获取密码@Overridepublic String getPassword() {return user.getPwd();}// 覆盖UserDetails接口中的getUsername方法,返回用户的用户名// 这里通过调用user对象的getUserName方法获取用户名,并注释说明有的地方可能会用email作为用户名,这里还是使用userName@Overridepublic String getUsername() {// 用户名:有的地方可能会用email作为用户名,我们这还是userNamereturn user.getUserName();}// 覆盖UserDetails接口中的isAccountNonExpired方法,判断账户是否过期// 这里直接返回true,表示账户不过期@Overridepublic boolean isAccountNonExpired() {return true;}// 覆盖UserDetails接口中的isAccountNonLocked方法,判断账户是否被锁定// 这里直接返回true,表示账户未被锁定@Overridepublic boolean isAccountNonLocked() {return true;}// 覆盖UserDetails接口中的isCredentialsNonExpired方法,判断凭证是否过期// 这里直接返回true,表示凭证不过期@Overridepublic boolean isCredentialsNonExpired() {return true;}// 覆盖UserDetails接口中的isEnabled方法,判断用户是否启用// 这里直接返回true,表示用户启用状态为true@Overridepublic boolean isEnabled() {return true;}
}

虽然我们系统里面有自己的 user 了,但是为了适配,所以就 聚合 进来。

然后是如何查询DB,肯定得有个 Service 去查询,我们已经有自己的UserService了,但是很可惜,spring security 这个地方也有自己的规范,我们自己写的user Service,人家不认,唉。

没办法,重新写个Service,自己写都写了,也不能丢了,所以 依照上面的操作,还是聚合进来。

@Service
@Slf4j
public class UserDetailService implements UserDetailsService {@ResourceUserService userService;/*** 根据用户名直接从DB中查询用户数据,作为登录校验的依据* @param username* @return* @throws UsernameNotFoundException*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userService.getByUsername(username);if (user == null) {log.info("username not found");throw new UsernameNotFoundException("username not found");}SecurityUser securityUser = new SecurityUser();securityUser.setUser(user);return securityUser;}
}

核心逻辑 是,我们还是用之前的方法拿到 User,但为了适配,就塞到 SecurityUser 里面去。

UserDetailsServicespring security认可的接口,我们得实现这个接口,并且实现loadUserByUsername方法,这个方法在spring security的认证逻辑里面会用到。目的就是拿到DB中真实的User,跟我们登录的账号密码进行比对。

5、校验密码是否正确

很多时候我们的密码是要进行加密的,但是我们登录肯定传的是明文密码,所以需要转换后再去比对。

这个 校验密码 的逻辑,需要写在spring security配置类 中。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@ResourceUserDetailService userService;/*** 新增security账户* @param auth* @throws Exception*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService).passwordEncoder(new PasswordEncoder() {@Overridepublic String encode(CharSequence rawPassword) {return rawPassword.toString();}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {return rawPassword.equals(encodedPassword);}});}}

因为我们的项目并没有对密码加密,所以就直接比较了。

在 LoginController 中,我们用到了AuthenticationManager这个对象,需要在配置类中注册。

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {// 身份验证管理器, 直接继承即可.return super.authenticationManagerBean();
} 

AuthenticationManager 是 Spring Security框架中的一个核心接口,它负责处理身份验证请求。
在认证过程中,用户提交身份验证信息(如用户名和密码),AuthenticationManager 会验证这些信息的有效性。

最后是 路由 的相关配置

    @Override  protected void configure(HttpSecurity http) throws Exception {  http  // 禁用跨站请求伪造保护  .csrf().disable()   // 设置会话管理策略为无会话,因为我们使用token作为信息传递介质  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)   .and()  // 进行认证请求的配置  .authorizeRequests()   // 将所有登入和注册的接口放开,这些都是无需认证就访问的  .antMatchers("/security/login").anonymous()   // 除了上面的那些,剩下的任何接口请求都需要经过认证  .anyRequest().authenticated()   .and()  // 允许跨域请求  .cors()   ;  // 在UsernamePasswordAuthenticationFilter之前添加JWT认证过滤器  http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);  }

这段代码是Spring Security框架中用于配置HTTP安全的部分。它主要涉及到跨站请求伪造(CSRF)的禁用、会话管理策略的设置、认证请求的配置以及跨域请求的允许。同时,还添加了一个JWT(JSON Web Token)认证过滤器。

因为我们项目用到了jwt,所以在进行账号密码验证之前,要先走jwt的过滤器。

jwt过滤器代码如下:

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {@ResourceJWTUtil jwtUtil;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, ServletException, IOException {//获取tokenString token = request.getHeader("token");if (!StringUtils.hasText(token)) {//token为空的话, 就不管它, 让SpringSecurity中的其他过滤器处理请求//请求放行filterChain.doFilter(request, response);return;}//token不为空时, 解析tokenUser user = null;try {user = jwtUtil.verify(token);} catch (Exception e) {// 过滤器中抛出的异常,无法被统一异常捕获,所以在这里直接返回e.printStackTrace();Result result = new Result();result.setCode(403);result.setMsg("Token无效:" + e.getMessage());WebUtils.response(response,result);return;}SecurityUser securityUser = new SecurityUser();securityUser.setUser(user);//将用户安全信息存入SecurityContextHolder, 在之后SpringSecurity的过滤器就不会拦截UsernamePasswordAuthenticationToken authenticationToken =new UsernamePasswordAuthenticationToken(securityUser, null, null);SecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request, response);}
}  

流程参考这个图:
在这里插入图片描述

如果校验成功了,那么在登录方法中就会往下走,生成token返回,结束。

6、全局异常返回

认证过程中,难免出现各种异常,我们一般会做一个通用的返回

Result

@Data
public class Result implements Serializable {private int code;private String msg;private Object data;public static Result succ(Object data) {return success(200, "操作成功", data);}public static Result error(String msg) {return error(400, msg, null);}public static Result success (int code, String msg, Object data) {Result result = new Result();result.setCode(code);result.setMsg(msg);result.setData(data);return result;}public static Result error (int code, String msg, Object data) {Result result = new Result();result.setCode(code);result.setMsg(msg);result.setData(data);return result;}
}

GlobalExceptionHandler

/*** 全局异常处理*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 400 错误:运行时异常* @param e* @return*/@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(value = RuntimeException.class)public Result handler(RuntimeException e) {log.error("运行时异常:----------------{}", e.getMessage());return Result.error(e.getMessage());}/*** 403 错误:权限不足* @param e* @return*/@ResponseStatus(HttpStatus.FORBIDDEN)@ExceptionHandler(value = AccessDeniedException.class)public Result handler(AccessDeniedException e) {log.info("security权限不足:----------------{}", e.getMessage());return Result.error("权限不足");}/*** 400 错误:异常请求-方法参数不匹配* @param e* @return*/@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(value = MethodArgumentNotValidException.class)public Result handler(MethodArgumentNotValidException e) {log.info("实体校验异常:----------------{}", e.getMessage());BindingResult bindingResult = e.getBindingResult();ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();return Result.error(objectError.getDefaultMessage());}/*** 400 错误:异常请求-非法参数* @param e* @return*/@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(value = IllegalArgumentException.class)public Result handler(IllegalArgumentException e) {log.error("Assert异常:----------------{}", e.getMessage());return Result.error(e.getMessage());}}

二、原理亮明

Spring Security 它专注于身份验证和授权,并可根据需求进行配置和自定义。在实际应用中,了解身份验证组件的概念对于使用 Spring Security 进行实现和自定义非常有帮助。

1、没有使用 Spring Security

如果我们没有使用 Spring Security,那么请求将被 DispatcherServlet 拦截。

  • DispatcherServlet 服务分发器
    它拦截任何 HTTP 请求并将其转发到正确的控制器。
    在 Spring Boot 中,DispatcherServlet 会被自动配置。
    在这里插入图片描述

2、DispatcherServlet 是如何工作的

在深入了解 Spring Security 之前,让我们先了解一下 DispatcherServlet 如何分发请求。
当我们在一个端点(比如 /hello/world)发出请求时,DispatcherServlet 会如何处理它?

DispatcherServlet 创建了一个 IOC 容器,它是 Spring Framework 的核心组件之一,用于管理 bean 的创建和依赖关系。DispatcherServlet 创建的是 WebApplicationContext,这是一个专门用于 Web 应用程序的 IOC 容器。WebApplicationContext 是根据配置文件由 DispatcherServlet 进行配置的。

该 IOC 容器 会创建控制器 bean 的实例。当请求到达时,DispatcherServlet 会使用 IOC 容器 查找适当的 控制器 bean,并 委托 给它来 处理请求。

3、使用 Spring Security

当将 Spring Security 添加到 Spring Boot 应用程序中时,所有请求在到达 DispatcherServlet 之前 都会被 Spring Security 拦截。

在这里插入图片描述

4、认证 流程

身份验证请求和响应

虽然 Spring Security 可以与不同类型的身份验证方法一起使用,但在本文中,我们讨论的是 用户名和密码 方式的 身份验证,以便深入了解完整的身份验证流程。

  1. Filter Chain 在将请求转发给 Dispatcher Servlet 之前拦截传入请求。

  2. 请求进入认证过滤器(其中一个过滤器是 UsernamePasswordAuthenticationFilter)。

  3. 过滤器从请求(HttpServletRequest 对象)中提取用户名和密码。

  4. 然后使用凭据创建 UsernamePasswordAuthenticationToken

  5. 调用 AuthenticationManager 的 authenticate() 方法。

  6. AuthenticationManager 的 authenticate() 方法实现将尝试使用其拥有的 AuthenticationProvider 之一进行身份验证。

  7. 如果一个身份验证提供程序能够成功进行身份验证,它将返回一个包含凭据和权限的完整的 UsernamePasswordAuthenticationToken。

  8. 提供程序返回的此令牌用于在 Spring Security 上下文中将用户设置为已认证。

  9. 一旦用户通过身份验证,请求就会被转发到处理请求的 DispatcherServlet。

5、认证流程 中涉及到的 组件

5.1 什么是过滤器

Spring Filter 是一个组件,可以拦截任何传入请求,并在将其传递给 DispatcherServlet 之前执行某些操作。
过滤器可以处理请求,然后将其转发到 Filter Chain 中的下一个过滤器,或者可以停止并发送回 HTTP 响应。其中一个过滤器是存在于 FilterChain 中的 UsernamePasswordAuthenticationFilter。此过滤器尝试查找 HTTP Post 请求中传递的用户名和密码,如果找到,则尝试使用凭据对用户进行身份验证。
我们可以创建自己的 Filter 并将其添加到 SecurityFilterChain 中,以提供自己的逻辑来处理请求。

5.2 什么是 AuthenticationManager

AuthenticationManager 是一个接口,用于处理 身份验证 的过程。它只有一个方法 authenticate(Authentication authentication),该方法将一个身份验证对象作为参数,并返回 已经认证的 身份验证对象。身份验证对象通常是一个包含用户名和密码等凭据的 AuthenticationToken 对象。

Authentication authenticate(Authentication authentication) throws AuthenticationException;   

AuthenticationManager 的 实现类 是 ProviderManager 类,它提供了 authenticate() 方法的逻辑。
我们可以提供我们自己的 AuthenticationProvider 实现类 或 使用默认实现。

5.3 什么是 ProviderManager

实现 了 AuthenticationManager 接口 并覆盖了 authenticate() 方法。
它使用一组 AuthenticationProvider 来验证 Authentication 对象中发送的凭据。如果 AuthenticationProvider 支持身份验证类型,则将用于验证用户。如果没有提供者支持身份验证类型,则将抛 AuthenticationException。

每个身份验证提供程序的 supports() 方法用于检查它是否可以支持所需的身份验证类型。

5.4 什么是 AuthenticationProvider

AuthenticationProvider 是一个接口,用于定义验证用户的协议。它负责接收 Authentication 对象(表示用户凭据)并返回已经认证的 Authentication 对象,如果凭据有效。如果凭据无效,则 AuthenticationProvider 应该抛出 AuthenticationException。

AuthenticationProvider 接口有两个方法:

  • authenticate():此方法接受 Authentication 对象作为输入,并在凭据有效时返回已认证的 Authentication 对象。如果凭据无效,则 AuthenticationProvider 应该抛出 AuthenticationException。

  • supports():此方法接受 Authentication 对象作为输入,并且如果 AuthenticationProvider 可以验证该对象,则返回 true。如果 AuthenticationProvider 无法验证该对象,则应返回 false。

Spring Security 中的默认 AuthenticationProvider 是 DaoAuthenticationProvider。此提供程序使用 UserDetailsService 从数据库加载用户详细信息。如果用户凭据与数据库中的详细信息匹配,则 DaoAuthenticationProvider 将返回已经认证的 Authentication 对象。

我们可以添加我们自己的 AuthenticationProvider 实现来提供不同的身份验证方法。

5.5 身份验证和 UsernamePasswordAuthenticationToken

Authentication 和 UsernamePasswordAuthenticationToken 是什么?

  • Authentication

这是 Spring Security 中的一个接口,表示传入身份验证请求的令牌或已认证的主体(表示一个实体,比如个人)AuthenticationManager.authenticate() 方法。

提供的一些方法为:

 Collection<? extends GrantedAuthority> getAuthorities();Object getCredentials();boolean isAuthenticated();void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;  
  • UsernamePasswordAuthenticationToken

此类扩展了 AbstractAuthenticationToken 类(身份验证对象的基类),可用于用户名/密码身份验证请求。

此类有两个构造函数:

public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {super((Collection)null);this.principal = principal;this.credentials = credentials;this.setAuthenticated(false);
}public UsernamePasswordAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {super(authorities);this.principal = principal;this.credentials = credentials;super.setAuthenticated(true);
}

第一个构造函数可用于传入请求以创建未经身份验证的 Authentication 对象。

Authentication authentication = new UsernamePasswordAuthenticationToken(username,password);   

第二个构造函数可用于创建完全经过身份验证的 Authentication 对象。

Authentication authToken = new UsernamePasswordAuthenticationToken(username, password, userAuthorities);   

然后,此完全经过身份验证的 Authentication 对象从 AuthenticationProvider/AuthenticationManager 返回并表示已认证的用户。然后将此已认证的对象设置在 SecurityContext 中。Spring Security 中的 SecurityContext 是当前执行线程的安全上下文的表示。它包含有关当前已认证用户的信息,例如其用户名、权限和会话信息。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

HTMLCSS 打造的酷炫菜单选项卡

效果演示 具有视觉吸引力的菜单选项 HTML <div class"card"><ul><li class"iso-pro"><span></span><span></span><span></span><a href""><svgviewBox"0 0 320 512&quo…

【linux】网络基础 ---- 传输层

1. UDP协议 &#xff08;一&#xff09;UDP协议端格式 注意&#xff1a; 16位UDP长度, 表示整个数据报(UDP首部UDP数据)的最大长度16位UDP检验和&#xff0c;能判断是否出现数据丢失等问题如果校验和出错, 就会直接丢弃 UDP报头本质上也是一个结构体&#xff1a; 操作系统内有…

软件包管理

软件安装 软件包管理器 APT&#xff08;Advanced Package Tool&#xff09;&#xff1a; 发行版&#xff1a;主要用于 Debian 及其衍生版&#xff08;如 Ubuntu&#xff09;。 常用命令&#xff1a; apt-get install &#xff1a;安装软件包。 apt-get update&#xff1a;更新…

[项目代码] YOLOv5 铁路工人安全帽安全背心识别 [目标检测]

YOLOv5是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv5具有更高的…

Linux逻辑卷

文章目录 逻辑卷 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Linux专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月12日11点09分 逻辑卷 LVM逻辑卷管理是Linux环境中对磁盘分区进行管理的一种机制&#xff0c;建立在硬盘和分区之…

【设计模式】创建型设计模式-工厂模式的实现

工厂模式实现 定义例子UML类图理解Java代码实现总结 定义 工厂方法模式定义了一个接口用于创建对象&#xff0c;该模式由子类决定实例化哪个工厂类。该模式把类的实例化推迟到了子类。 例子 通过一个公共的类方法来管理画图对象的创建。 UML类图理解 Java代码实现 定义接口…

Spring Boot实战:编程训练系统开发手册

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理编程训练系统的相关信息成为必然。开发合适…

方案丨车险保单OCR:3秒钟完成保单审核

在涉及车辆交易的各种情况下&#xff0c;记录和管理车险保单信息是一项必不可少的任务。然而&#xff0c;面对数量庞大的电子保单&#xff0c;传统的手工录入方式显得尤为低效——它不仅消耗大量时间&#xff0c;而且容易出现错误&#xff0c;这不仅影响了用户的满意度&#xf…

性能测试|JMeter接口与性能测试项目

前言 在软件开发和运维过程中&#xff0c;接口性能测试是一项至关重要的工作。JMeter作为一款开源的Java应用&#xff0c;被广泛用于进行各种性能测试&#xff0c;包括接口性能测试。本文将详细介绍如何使用JMeter进行接口性能测试的过程和步骤。 JMeter是Apache组织开发的基…

嵌入式硬件电子电路设计(五)MOS管详解(NMOS、PMOS、三极管跟mos管的区别)

引言&#xff1a;在我们的日常使用中&#xff0c;MOS就是个纯粹的电子开关&#xff0c;虽然MOS管也有放大作用&#xff0c;但是几乎用不到&#xff0c;只用它的开关作用&#xff0c;一般的电机驱动&#xff0c;开关电源&#xff0c;逆变器等大功率设备&#xff0c;全部使用MOS管…

如何优化开放数据湖仓一体的性能

数据湖仓一体架构由 Apache Hudi、Apache Iceberg 和 Delta Lake 等开放表格式提供支持&#xff0c;提供了一种开放且经济高效的方式来管理组织不断增长的数据和分析需求。它提供了在同一数据存储上运行并发事务的可靠性&#xff0c;从而提高了效率。数据湖仓一体支持关键功能&…

比较基因组分析

比较基因组分析&#xff08;Comparative Genomics Analysis&#xff09;是一门通过比较不同物种或个体的基因组序列来研究其相似性与差异性的科学方法。它有助于揭示物种间的进化关系、基因功能、生物适应性及潜在的疾病机制。近年来&#xff0c;随着高通量测序技术的发展&…

leetcode 148. 排序链表 中等

给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#xff1a; …

基于单片机的智能小车(论文+源码)

1系统整体方案 此次多功能智能小车的设计系统&#xff0c;其整个控制电路的框架如下图所示。整个系统采用STM32单片机为控制器其中&#xff1a;LCD液晶负责显示当前信息,蜂鸣器负责特殊情况下进行报警提醒,红外遥控模块方便用户进行远程操作小车,电机模块拟采用前驱的方式&…

基于matlab的CNN食物识别分类系统,matlab深度学习分类,训练+数据集+界面

文章目录 前言🎓一、数据集准备🎓二、模型训练🍀🍀1.初始化🍀🍀2.加载数据集🍀🍀3.划分数据集,并保存到新的文件夹🍀🍀4.可视化数据集🍀🍀5.模型构建🍀🍀6.数据增强🍀🍀7.设置训练参数🍀🍀8.训练与测试🎓三、模型测试🍀🍀1.初始化�…

UCSD:LLM通过工具使用解决科学问题

&#x1f4d6;标题&#xff1a;Adapting While Learning: Grounding LLMs for Scientific Problems with Intelligent Tool Usage Adaptation &#x1f310;来源&#xff1a;arXiv, 2411.00412 &#x1f31f;摘要 &#x1f538;大型语言模型&#xff08;LLMs&#xff09;在解…

【时间之外】IT人求职和创业应知【34】-人和机器人,机器人更可靠

目录 新闻一&#xff1a;人形机器人产业持续高速增长&#xff0c;2026年中国市场规模将突破200亿元 新闻二&#xff1a;AI技术驱动设备厂商格局变化&#xff0c;部分厂商市占率快速提升 新闻三&#xff1a;华为与江淮汽车携手打造超高端品牌“尊界”&#xff0c;计划于明年春…

MyBatis及相关文件配置

MyBatis是一款优秀的持久层框架&#xff0c;它支持定制化SQL、存储过程以及高级映射。以下是对MyBatis的详细讲解&#xff1a; 一、MyBatis的起源与发展 MyBatis最初是Apache的一个开源项目iBATIS&#xff0c;2010年迁移到Google Code并改名为MyBatis&#xff0c;2013年11月又…

【FastAPI】1-url参数

fastapi的核心功能是提供HTTP请求接口 “幂等”和“非幂等” 幂等&#xff08;idempotent&#xff09;&#xff1a;如果一个方法重复执行多次&#xff0c;产生的效果是一样的&#xff0c;那么这个方法就是幂等的 “Methods can also have the property of “idempotence” in …

CentOS Stream 9设置静态IP

CentOS Stream 9设置静态IP CentOS Stream 9作为CentOS Stream发行版的下一个主要版本&#xff0c;已经发布有一段时间&#xff0c;但与目前广泛使用的CentOS7有较大区别。安装试用Stream 9的过程中&#xff0c;就发现设置静态IP的方式和CentOS7/8差别较大&#xff0c;在此记录…