目录

权限控制

相关框架

SpringSecurity

springsecurity使用流程

1、搭建环境实现默认用户名和密码登录

2、使用数据库表中定义好的用户名和密码访问实现等值密码匹配

1)sql文件

2)搭建jdbc或者mybatis或者mybatis-plus环境

3)配置mybatis-plus环境

4)使用mybatisX 生成基本的service和mapper

5)创建一个类实现UserDetailsService接口 ,重写方法(根据用户名到数据库中查找用户对象)

6)创建一个LoginUser实现UserDetails接口,封装用户信息

3、加密机制 自定义密码匹配器

1)创建加密对象

2)使用测试类,生成临时密码,测试匹配方法

4、自定义登录接口

5、token字符串的生成


权限控制

一、认证:是否登录成功。

二、授权:权限控制,授予权限、校验权限。

相关框架

一、shiro

Shiro 是 apache权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。 Shiro 是一个强大而灵活的开源安全框架,能够非常清晰的处理认证授权管理会话以及密码加密

二、springsecurity

Spring Security 是 Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰

富的功能,社区资源也比Shiro丰富。

一般来说中大型的项目都是使用SpringSecurity来做安全框架。

小项目用Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。

SpringSecurity

springsecurity 和 其他组件的简单交互

前后端分离场景下,登录校验流程的核心思路:token。 Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生 成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无 需再次带上用户名和密码。

使用token机制的身份验证方法,在服务器端不需要存储用户的登录记录。

JWT:JWT全面解读、详细使用步骤 - 简书

springsecurity使用流程

1、搭建环境实现默认用户名和密码登录

springboot环境+springweb+springsecurity权限jar包

访问目标方法时,自动跳转到/login接口,输入用户名user和默认密码,登录成功后,自动跳转到目标方法。

localhost:8080/login

2、使用数据库表中定义好的用户名和密码访问实现等值密码匹配

1)sql文件
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`user_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NULL' COMMENT '用户名',`nick_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NULL' COMMENT '昵称',`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NULL' COMMENT '密码',`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '账号状态(0正常 1停用)',`email` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱',`phonenumber` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '手机号',`sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户性别(0男,1女,2未知)',`avatar` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像',`user_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '用户类型(0管理员,1普通用户)',`create_by` bigint(20) NULL DEFAULT NULL COMMENT '创建人的用户id',`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',`update_by` bigint(20) NULL DEFAULT NULL COMMENT '更新人',`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',`del_flag` int(11) NULL DEFAULT 0 COMMENT '删除标志(0代表未删除,1代表已删除)',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
​INSERT INTO `sys_user` VALUES (1, '张三', '张三', '{noop}1234', '0', NULL, NULL, NULL, NULL, '1', NULL, NULL, NULL, NULL, 0);
2)搭建jdbc或者mybatis或者mybatis-plus环境
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version>
</dependency>
3)配置mybatis-plus环境
server:port: 8080
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springsecurityusername: rootpassword: 123456
mybatis-plus:configuration:map-underscore-to-camel-case: truetype-aliases-package: com.hl.springsecurity01.domainmapper-locations: classpath:/mapper/*.xml
4)使用mybatisX 生成基本的service和mapper

 

5)创建一个类实现UserDetailsService接口 ,重写方法(根据用户名到数据库中查找用户对象)
package com.hl.springsecurity01.security;
​
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hl.springsecurity01.domain.SysUser;
import com.hl.springsecurity01.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
​
import java.util.List;
​
@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate SysUserService sysUserService;/*根据用户名查找用户对象*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据用户名,到数据库表中,查找用户对象QueryWrapper queryWrapper = new QueryWrapper();queryWrapper.eq("user_name", username);List<SysUser> list = sysUserService.list(queryWrapper);//判断用户是否存在LoginUser user = null;if(list != null && list.size() > 0){SysUser sysUser = list.get(0);//封装数据到UserDetails接口实现类对象中user = new LoginUser(sysUser);}return user;}
}
6)创建一个LoginUser实现UserDetails接口,封装用户信息
package com.hl.springsecurity01.security;
​
import com.hl.springsecurity01.domain.SysUser;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
​
import java.util.Collection;
import java.util.Collections;
/*
创建类实现UsersDetail接口,存储当前登录成功的用户信息*/
@Data
public class LoginUser implements UserDetails {
​private SysUser sysUser;
​public LoginUser() {}public LoginUser(SysUser sysUser) {this.sysUser = sysUser;}
​//返回用户权限信息,返回权限列表@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return Collections.emptyList();}
​@Overridepublic String getPassword() {return sysUser.getPassword();}
​@Overridepublic String getUsername() {return sysUser.getUserName();}
​@Overridepublic boolean isAccountNonExpired() {return true;}
​@Overridepublic boolean isAccountNonLocked() {return true;}
​@Overridepublic boolean isCredentialsNonExpired() {return true;}
​@Overridepublic boolean isEnabled() {return true;}
}

3、加密机制 自定义密码匹配器

1)创建加密对象
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {/*创建加密对象(密码匹配器对象)*/@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
}
2)使用测试类,生成临时密码,测试匹配方法
@SpringBootTest
class Springsecurity01ApplicationTests {@Autowiredprivate PasswordEncoder passwordEncoder;
​@Testvoid contextLoads() {String pwd = passwordEncoder.encode("1234");System.out.println(pwd);//$2a$10$DpNgEn0fiYStJJ/EoYxf7uhBOMnuqK/UdBKmexX5KrEVPLuGQ0LsS//$2a$10$sLUel1CyTVY1kDWM5BwlNu1WMLMqlys00NIir0SiEgR0A5ItM1Vda//比对密码boolean flag1 = passwordEncoder.matches("1234", "$2a$10$DpNgEn0fiYStJJ/EoYxf7uhBOMnuqK/UdBKmexX5KrEVPLuGQ0LsS");boolean flag2 = passwordEncoder.matches("1234", "$2a$10$sLUel1CyTVY1kDWM5BwlNu1WMLMqlys00NIir0SiEgR0A5ItM1Vda");System.out.println(flag1);System.out.println(flag2);}
​
}
$2a$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
├─┬─┼──┬─┼──────────────┼───────────────────────────────────│ │  │  │      │                     │ │  │  │      └─ 哈希值(31字节)│ │  │  └─ 盐值(22字符,16字节)│ │  └─ cost参数(12 → 2^12=4096轮迭代)│ └─ 算法版本(2a)└─ 固定前缀
$<算法版本>$<cost>$<salt><hash>

4、自定义登录接口

@RestController
public class LoginController {@Autowiredprivate LoginService loginService;@RequestMapping("/login")public R login(String username, String password) throws AuthenticationException {//调用servicereturn loginService.login(username, password);}
}
public interface LoginService {public R login(String username, String password) throws AuthenticationException;
}
@Service
public class LoginServiceImpl implements LoginService {@Autowiredprivate AuthenticationManager authenticationManager;@Overridepublic R login(String username, String password) throws AuthenticationException {UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username, password);//调用认证提供器的认证方法,进行用户名,密码认证Authentication authentication = authenticationManager.authenticate(token);//根据返回值判断是否认证成功if(authentication == null){//认证失败throw  new AuthenticationException("用户名或者密码错误");}if(authentication.isAuthenticated()){//认证成功//返回 code ,msg,tokenreturn R.ok("token.............","认证成功");}return null;}
}
package com.hl.springsecurity01.security;
​
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {/*创建加密对象(密码匹配器对象)*/@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()// 对于登录接口 允许匿名访问.antMatchers("/login").anonymous()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated();}@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}

 将数据库密码字段换成生成的加密字段$2a$10$DpNgEn0fiYStJJ/EoYxf7uhBOMnuqK/UdBKmexX5KrEVPLuGQ0LsS

登录成功,看到json返回,失败,没有任何提示。

5、token字符串的生成

<!--生成token-->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>

JwtUtil工具类

package com.hl.springsecurity01.util;
​
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
​
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;
​
/*** JWT工具类*/
public class JwtUtil {//有效期为public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000  一个小时//设置秘钥明文public static final String JWT_KEY = "test";
​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();}
​
​/*** 生成加密后的秘钥 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;}
​/*** 解析jwt** @param jwt* @return* @throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();}
​/***   用于测试*/public static void main(String[] args) throws Exception {
//        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjYWM2ZDVhZi1mNjVlLTQ0MDAtYjcxMi0zYWEwOGIyOTIwYjQiLCJzdWIiOiJzZyIsImlzcyI6InNnIiwiaWF0IjoxNjM4MTA2NzEyLCJleHAiOjE2MzgxMTAzMTJ9.JVsSbkP94wuczb4QryQbAke3ysBDIL5ou8fWsbt_ebg";
//        Claims claims = parseJWT(token);
//        System.out.println(claims);String token = createJWT("1");String token1 = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlM2UzMGE0ZjhhMGE0OTQ1ODNjMzZlZmNjMWQ3YzQ4YiIsInN1YiI6IjEiLCJpc3MiOiJzZyIsImlhdCI6MTc1MTUzMjI0MiwiZXhwIjoxNzUxNTM1ODQyfQ.ALfU833lUe1bCRlsAwcDd_mwD5j3sCtFCO3Ue1E-WWw";System.out.println(token);Claims claims = parseJWT(token1);System.out.println(claims);}
​
}
package com.hl.springsecurity01.service.impl;
​
import com.hl.springsecurity01.domain.R;
import com.hl.springsecurity01.security.LoginUser;
import com.hl.springsecurity01.service.LoginService;
import com.hl.springsecurity01.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
​
import javax.security.sasl.AuthenticationException;
​
@Service
public class LoginServiceImpl implements LoginService {@Autowiredprivate AuthenticationManager authenticationManager;@Overridepublic R login(String username, String password) throws AuthenticationException {UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username, password);//调用认证提供器的认证方法,进行用户名,密码认证Authentication authentication = authenticationManager.authenticate(token);//根据返回值判断是否认证成功if(authentication == null){//认证失败throw  new AuthenticationException("用户名或者密码错误");}if(authentication.isAuthenticated()){//认证成功//获取用户身份 LoginUserLoginUser user = (LoginUser) authentication.getPrincipal();//获取用户idLong id = user.getSysUser().getId();//根据用户id,生成tokenString token2 = JwtUtil.createJWT(id+"");//返回 code ,msg,tokenreturn R.ok(token2,"认证成功");}return null;}
}

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 Ubuntu 22.04 上使用 Minikube 部署 Go 应用到 Kubernetes

文章目录 环境说明目标步骤与问题解决1. 构建 Go 应用和 Docker 镜像问题 1&#xff1a;Go 依赖下载卡住问题 2&#xff1a;Docker 镜像拉取失败 2. 设置 Minikube 集群安装 Minikube问题 3&#xff1a;Minikube 启动失败问题 4&#xff1a;Minikube 镜像拉取失败 3. 部署 Kube…

Android Studio-Git的使用指南

一、git的基本使用流程 git clone 克隆远程资源到本地目录&#xff0c;作为工作目录&#xff1b;然后在本地的克隆目录上添加或修改文件&#xff1b;如果远程修改了&#xff0c;需要同步远程的内容&#xff0c;直接git pull就可以更新本地的文件&#xff1b;本地在修改之后&…

【github】想fork的项目变为私有副本

在 GitHub 上&#xff0c;所有的 fork 都会继承其上游仓库&#xff08;upstream&#xff09;的可见性&#xff08;visibility&#xff09;设置&#xff1a; 可见性继承 如果你 fork 的原仓库是 public&#xff0c;那么你的 fork 也必须是 public。如果原仓库是 private&#xf…

微软发布新一代存储优化型虚拟机:Azure Laosv4、Lasv4 和 Lsv4 系列

微软宣布&#xff0c;全新一代存储优化型虚拟机——Azure Laosv4、Lasv4 和 Lsv4 系列已正式面世。 与前一代虚拟机系列相比&#xff0c;全新的 L 系列虚拟机实现了重大突破。它支持高达 23TB 的本地 NVMe SSD&#xff0c;在 CPU、网络以及远程存储性能方面均有显著提升。该系…

python调用pybind11导出的pyd,出现UnicodeDecodeError

python调用pybind11导出的pyd&#xff0c;出现UnicodeDecodeError 1. 问题描述 举个例子&#xff0c;当有以下C代码以及Pybind11的绑定代码时&#xff0c;在python访问包含中文的Name和Value会有UnicodeDecodeError的异常&#xff01; class VxUserProp{public:VxUserProp();…

MySQL别名在GROUP BY中的使用规则

-- 设置变量&#xff1a;SET earliest_date ... 用于定义并赋值一个用户变量 earliest_date。 -- 用户定义的变量必须以 符号开头&#xff0c;例如 earliest_date。 -- 符号是MySQL中用户变量的标识符&#xff0c;用于区分系统变量和用户变量。 SET earliest_date (SELECT …

2025.7.4总结

感恩环节:感谢今日工作顺利度过&#xff0c;明天终于能美美的睡个懒觉了。感谢这周有个美好的双休。今日去实验室参观设备&#xff0c;感谢我的一个同事解答了我关于硬件设备与所做软件业务之间的关系&#xff0c;通过控制器控制网元等相关设备&#xff0c;同时&#xff0c;虽然…

Prompt 精通之路(五)- 构建你的“AI 指令系统”:超越简单提问的 CRISPE 与 APE 框架

&#x1f680; Prompt 精通之路&#xff1a;系列文章导航 第一篇&#xff1a;[本文] AI 时代的新语言&#xff1a;到底什么是 Prompt&#xff1f;为什么它如此重要&#xff1f;第二篇&#xff1a;告别废话&#xff01;掌握这 4 个黄金法则&#xff0c;让你的 Prompt 精准有效第…

#NFT艺术品哈希值唯一性与《民法典》“网络虚拟财产”认定的冲突

首席数据官高鹏律师数字经济团队创作&#xff0c;AI辅助 一、当区块链的「绝对唯一」遇上法律的「弹性空间」 每个NFT艺术品背后的哈希值&#xff0c;都像用数学密码刻在区块链上的指纹——世界上没有任何两个完全相同的编码。这种由0和1构筑的「数字DNA」&#xff0c;被技术信…

【arXiv2025】计算机视觉|即插即用|LBMamba:革新视觉模型效率,性能炸裂

论文地址&#xff1a;https://arxiv.org/pdf/2506.15976 代码地址&#xff1a;https://github.com/CiaoHe/bi-mamba 关注UP CV缝合怪&#xff0c;分享最计算机视觉新即插即用模块&#xff0c;并提供配套的论文资料与代码。 https://space.bilibili.com/473764881 摘要 Mamba…

【狂飙AGI】第7课:AGI-行业大模型(系列1)

目录 &#xff08;一&#xff09;服装史的GPT时刻&#xff08;二&#xff09;AI多学科诊疗系统&#xff08;三&#xff09;医疗大模型&#xff08;四&#xff09;生物医药大模型&#xff08;五&#xff09;教育大模型&#xff08;六&#xff09;心理大模型&#xff08;七&#…

(LeetCode 每日一题) 3307. 找出第 K 个字符 II (位运算、数学)

题目&#xff1a;3307. 找出第 K 个字符 II 思路&#xff1a;位运算&#xff0c;时间复杂度0(logk)。 当2^(i-1) <k 且 2^i>k &#xff0c;说明k在K2^i的右半段 &#xff0c;k和其前半段的某个字符有关系 即当k>K时&#xff0c;k是由k-K位置上的字符变化而来&#xf…

国产MCU学习Day4——CW32F030C8T6:独立看门狗功能全解析

CW32F030C8T6 看门狗功能概述 CW32F030C8T6 是芯源半导体&#xff08;WCH&#xff09;推出的 Cortex-M0 内核微控制器&#xff0c;内置独立看门狗&#xff08;IWDG&#xff09;和窗口看门狗&#xff08;WWDG&#xff09;&#xff0c;用于检测和恢复系统异常状态。 一.独立看门…

SAP升级过程中如何确保数据安全?

目录 升级过程中可能遇到的数据风险 升级前的准备工作 升级过程中的保护措施 升级后的验证工作 在数字化转型浪潮中&#xff0c;SAP系统作为企业核心业务运营的系统&#xff0c;其升级过程不仅关乎技术架构的革新&#xff0c;更直接关系到企业最宝贵的资产——数据安全。一…

Vue 3 + Element Plus 常见开发问题与解决方案手册

&#x1f31f;Vue 3 Element Plus 常见开发问题与解决方案手册 &#x1f9e0; 本文整理了常见但容易混淆的几个 Vue 3 前端开发问题&#xff0c;包括插槽、原型链、响应式数据处理、v-model 报错、样式阴影控制等&#xff0c;建议收藏学习&#xff01; &#x1f4cc;一、动态插…

Spring Boot + 本地部署大模型实现:安全性与可靠性保障

在将大语言模型集成到 Spring Boot 应用中时&#xff0c;安全性和可靠性是两个关键因素。本地部署的大模型虽然提供了强大的功能&#xff0c;但也可能带来一些安全风险&#xff0c;如数据泄露、模型被恶意利用等。本文将介绍如何在 Spring Boot 应用中保障本地部署大模型的安全…

Zookeeper 客户端 .net访问框架 ZookeeperNetEx项目开发编译

一、项目简介 ZooKeeperNetEx 项目是一个针对.NET开发的异步客户端库&#xff0c;旨在为开发者提供高效且可靠的分布式协调服务。‌ 该项目完全基于任务异步编程&#xff0c;兼容.NET 4.61及以上版本&#xff0c;包括.NET Core。ZooKeeperNetEx严格遵循官方Java客户端的逻辑&am…

【学习笔记】因果推理导论第2课

因果推理导论第2课 因果推断假设 前言一、假设1、 Ignorability / Exchangeability2、条件可交换 二、估计 前言 第一节课通过一些例子说明了为什么要做因果推断,以及通过控制混杂因素计算因果效应;这一节课将围绕为何控制混杂因素计算因果效应这一方法成立,讲述其涉及到的一些…

VASP 教程:VASP 机器学习力场微调

机器学习力场&#xff08;Machine-Learned Force Fields, MLFFs&#xff09;作为一种新兴的计算方法&#xff0c;已在第一性原理分子动力学&#xff08;Ab Initio Molecular Dynamics, AIMD&#xff09;模拟中展现出独特优势&#xff08;参见 VASP Wiki&#xff1a;Category:Ma…