Java阶段三Day06

news/2024/11/24 11:55:55/

Java阶段三Day06

文章目录

  • Java阶段三Day06
    • 同步请求和异步请求
    • 案例演示
      • 创建SpringBoot工程
      • application.properties
      • UserController
      • UserMapper
      • 静态页面
    • JSON
    • Spring Security
      • 引入`SpringSecurity`框架
      • 对项目的影响
      • 关于SpringSecurity的配置
      • 默认登录表单
      • 设置白名单
      • 模拟登录
      • 使用自己的页面进行登录
      • CSRF
      • 关闭跨域攻击防御机制
      • 通过真实数据进行登录
      • 统一异常处理
    • Security框架认证流程总结
  • 教师总结
    • 同步请求和异步请求
    • 创建SpringBoot工程
    • JSON
    • SpringSecurity框架流程
    • Security框架认证流程:

同步请求和异步请求

  • 同步:指单线程依次做几件事
  • 异步:指多线程同时做几件事
  • 同步请求:指客户端浏览器只有一个主线程,主线程既要负责页面渲染 \ 监听用户的页面操作还需要负责发请求,当主线程发出请求时,会将页面中的内容清空,直到服务器响应了数据之后再将响应的数据展示出来,这个过程称为页面的整体刷新,同步请求无法实现页面的局部刷新
  • 异步请求:指客户端浏览器由主线程否则页面渲染和监听用户的页面的操作,由子线程负责发出请求,当子线程请求到数据之后,可以把得到的数据显示到原页面中,这就是页面的局部刷新

案例演示

创建SpringBoot工程

  • 工程导入依赖3个√MyBatis FrameworkMySQL DriverSpring Web

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSKsYOQq-1685441210328)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530133033882.png)]

  • 在pom.xml添加以下依赖

    <!--引入Lombok依赖-->
    <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
    </dependency>
    <!--添加Knife4j依赖-->
    <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version>
    </dependency><!--添加spring-validation依赖-->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
# 设置MyBatis框架的映射(Mapper)配置文件的位置
mybatis.mapper-locations=classpath:mappers/*.xmllogging.level.com.liner=debug

UserController

@RestController
@RequestMapping("/v1/users/")
public class UserController {@Autowired(required = false)UserMapper mapper;@RequestMapping("reg")public ResultVO reg(@RequestBody UserRegDTO userRegDTO){System.out.println("userRegDTO = " + userRegDTO);//判断用户名是否存在UserVO userVO = mapper.selectByUsername(userRegDTO.getUsername());if (userVO!=null){return new ResultVO(StatusCode.USERNAME_ERROR);}User user = new User();BeanUtils.copyProperties(userRegDTO,user);user.setCreated(new Date());mapper.insert(user);//当给客户端响应的是Java对象时SpringMVC框架会自动将Java对象转成//Json格式的字符串,然后将字符串响应给客户端.return new ResultVO(StatusCode.SUCCESS);}
}

UserMapper

public interface UserMapper {UserVO selectByUsername(String username);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liner.mapper.UserMapper"><select id="selectByUsername" resultType="com.liner.pojo.vo.UserVO">SELECT id, password, nicknameFROM userWHERE username = #{username}</select></mapper>

静态页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>注册</title></head><body><div><input type="text" placeholder="用户名" v-model="user.username"><input type="text" placeholder="密码" v-model="user.password"><input type="text" placeholder="昵称" v-model="user.nickname"><input type="button" value="注册" @click="reg()"></div><!--引入vue框架文件--><script src="https://cdn.staticfile.org/vue/2.6.14/vue.min.js"></script><!--引入axios框架文件--><script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script><script>let v = new Vue({el:"body>div"data:{user:{username:"",password:"",nickname:""}}methods:{reg(){//发出异步请求response代表服务器响应对象//response.data得到响应的ResultVO对象  不是每一个请求都有dataaxios.post("/v1/users/reg",v.user).then(function (response) {//当接收到JSON格式的字符串的时候Axios框架会自动将JSON格式的字符串转成了JS的对象if (response.data.code === 1){alert("注册成功");location.href="/";  //localhost:8080}else{alert("用户已存在!")}})}}})</script></body>
</html>

JSON

JSON:JavaScript Object Notation 是一种轻量级数据交换格式(也称为数据封装格式)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9fHs2sGv-1685441210336)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530113056614.png)]

当服务器给客户端响应复杂数据时需要将数据封装到ava对象里面,但是Java对象不是跨平台的对象客户端是无法直接识别Java格式的对象的,这时候就需要将Java的对象先转成JSON格式的字符串,因为JSON字符串是跨平台的类型,客户端接收到JSON格式的字符串时,Axios框架会自动将其转成JS语言的对象

Spring Security

Spring Security是一个基于Spring框架的安全性认证和访问控制框架,主要用于保护Web应用程序。它提供了一组与安全相关的服务和类,使得开发者可以方便地为Web应用程序添加认证和访问控制功能。

主要作用:帮助我们进行登录的认证,和项目中涉及到权限时进行权限誓理操作

引入SpringSecurity框架

<!-- Spring Boot支持Spring Security的依赖项,用于处理认证与授权-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

对项目的影响

  • 所有的请求(包括根本不存在的)都必须登录,否则自动跳转到登录页面

  • 默认的用户名是user,密码是启用项目时在控制台提示的一串UUID值 ,如下图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HON8EUVm-1685441210337)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530150619410.png)]

  • 登录时,如果在打开登录页面后重启过服务器端,应该刷新登录页面,否则, 第1次输入并提交是无效的

  • 当登录成功后,会自动跳转到此前尝试访问的URL

  • 当登录成功后,可通过 /logout 退出登录

  • 默认不接受普通的POST请求,如果提交POST请求,会响应403(Forbidden)

关于SpringSecurity的配置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {}
}

默认登录表单

@Override
protected void configure(HttpSecurity http) throws Exception {//如果调用以下方法,当需要访问通过认证的资源,但是未通过认证时,将自动跳转到登录页面//如果未调用以下方法,将响应403http.formLogin();// super.configure(http);//不要保留调用父类同名方法的代码,不要保留!不要保留!不要保留!}

设置白名单

//设置白名单(不需要登录即可访问的资源)
String[] urls = {"/reg.html", "/login.html", "/v1/users/reg", "/v1/users/login"};
http.authorizeRequests()//对请求进行授权.mvcMatchers(urls)//匹配某些路径.permitAll() //直接许可,即不需要认证即可访问.anyRequest() //任意请求.authenticated();//要求通过认证的

模拟登录

  • 尝试登录用户名root,密码123456
  • 创建UserDetailsService接口的实现类,并实现loadUserByUsername方法
  • 此时进行登录时会自动调用此方法
  • 设置默认的密码编码为无编码
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Bean//配置密码加密的方式public PasswordEncoder passwordEncoder(){//NoOpPasswordEncoder.getInstance()获取一个无加密的实例return NoOpPasswordEncoder.getInstance();}
}
  • 登录成功需要响应一个UserDetail对象,如果响应的是一个null则会认为是用户名不存在
package com.liner.security;import org.springframework.security.core.userdetails.User;
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;@Service
public class UserDetailServiceImpl implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {System.out.println("username = " + username);//点击登录按钮UserDetails userDetail = User.builder().username("root").password("123456").disabled(false) //账号是否禁用.accountLocked(false)   //账号是否锁定.accountExpired(false)  //账号是否过期.credentialsExpired(false) //凭证是否过期.authorities("临时使用的权限") //权限.build();if (!username.equals("root")) {return null;    //代表用户名不存在}return userDetail;}
}

使用自己的页面进行登录

  • 需要在配置类中添加http.formLogin().loginPage("“/login.html");
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//配置自己的登录页面http.formLogin().loginPage("/login.html");//设置白名单String[] urls = {"/reg.html", "/login.html", "/v1/users/reg", "/v1/users/login"};http.authorizeHttpRequests()//对请求进行授权.mvcMatchers(urls)//匹配某些路径.permitAll() //直接许可,即不需要认证即可访问.anyRequest() //任意请求.authenticated();//要求通过认证的}
}
  • 使用自己的登录页面时,Security框架的登录认证流程不会自动启动,需要我们在UserController处理login请求时手动开启
  • 开启时需要在SpringSecurity框架的配置类中添加认证管理器
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Bean  //添加此注解的目的是为了在Controller中自动装配@Override//添加认证管理器protected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}
}
  • 添加后在自己的Controller里面添加以下代码才会触发UserDetailServicelmpl实现类
@Autowired
private AuthenticationManager authenticationManager;@RequestMapping("login")
public ResultVO login(@RequestBody UserLoginDTO userLoginDTO) {//通过认证管理器启动Security的认证流程返回认证结果对象Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userLoginDTO.getUsername(), userLoginDTO.getPassword()));//将认证结果保存到Security上下文中让Security框架记住登录状态SecurityContextHolder.getContext().setAuthentication(authenticate);//代码执行到这里时代表登录成功!如果登录失败Security框架会抛出异常return new ResultVO(StatusCode.SUCCESS);}

CSRF

  • CSRF指的是Cross-Site Request Forgery,中文翻译为“跨站请求伪造”,也称跨域攻击。它是一种网络攻击方式,攻击者利用用户在其他网站上登录过的身份信息,在用户不知情的情况下发送恶意请求来执行非法操作。

  • 攻击流程如下:

    • 用户在网站A上登录并获取Cookie
    • 用户在不注销网站A的情况下访问了网站B
    • 网站B通过HTML代码里插入恶意链接的形式,向网站A发出请求
    • 因为用户在网站A已经有了Cookie,所以请求被成功执行
    • 一旦攻击者成功发起CSRF攻击,就能够执行一些非法或损害用户隐私的操作,比如修改用户密码、盗取用户资料、转账等等。
  • 为了防止CSRF攻击,通常需要采取一些措施,如增加验证码、使用CSRF Token、验证Referer等。

关闭跨域攻击防御机制

  • SpringSecurity框架默认开启了跨域攻击的防护,通过携带CSRF token对请求进行判断
  • 因为现在都是前后端分离架构,客户端发出的请求都是异步请求,不存在form表单,所以不存在跨域攻击的问题,通过以下代码关闭跨域攻击,否则请求受限
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//禁用“防止伪造的跨域攻击”的防御机制http.csrf().disable();}
}

通过真实数据进行登录

@Service
public class UserDetailServiceImpl implements UserDetailsService {@Autowired(required = false)private UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {UserVO user = userMapper.selectByUsername(username);if (user == null) {return null;    //默认抛出 AuthenticationException 用户名找不到异常}UserDetails userDetail = User.builder().username(username).password(user.getPassword()).disabled(false) //账号是否禁用.accountLocked(false)   //账号是否锁定.accountExpired(false)  //账号是否过期.credentialsExpired(false) //凭证是否过期.authorities("临时使用的权限") //权限.build();//如果用户输入的密码和数据库中查询到的密码不一致则会抛出异常return userDetail;}
}

统一异常处理

  • 对用户名、密码错误导致抛出的异常进行统一异常处理
package com.liner.exception;import com.liner.response.ResultVO;
import com.liner.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;@Slf4j //lombok提供的日志注解,在代码层面会为我们提供一个org.slf4j.Logger对象
@RestControllerAdvice //=@ControllerAdvice+@ResponseBody
public class GlobalExceptionHandler {@ExceptionHandler({InternalAuthenticationServiceException.class, BadCredentialsException.class})public ResultVO handleAuthenticationServiceException(AuthenticationException e){log.error("异常信息 is {}",e.getMessage());//日志级别trace<debug<info<warn<errorif (e instanceof InternalAuthenticationServiceException){log.warn("用户名不存在!!!");return new ResultVO(StatusCode.USERNAME_ERROR,e.getMessage());}log.warn("密码错误!!!");return new ResultVO(StatusCode.PASSWORD_ERROR,e.getMessage());}
}

Security框架认证流程总结

  1. SecurityConfig配置类中配置好白名单,设置登录页面,关闭跨域攻击防御策略

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g7mJsRdw-1685448761167)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530195031993.png)]

  2. 当客户端请求路径不在白名单中,Security框架会自动将请求重定向到登录页面

  3. login.html登录页面中向/login地址发送登录请求时,服务器中UserController里面的login方法处理该请求

  4. login方法中通过认证管理器manager启动认证,将认证结果保存在Security上下文对象中

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sKdkF7ht-1685448761184)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530195603293.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3GxQ7cIb-1685448761185)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530200216950.png)]

  5. manager启动认证流程后会自动调用UserDetailServiceImpl里面的loadUserByUsername方法,在方法内部,调用UserMapper里面的查询方法通过用户名查询到UserVO

  6. 如果查询不到return null,此时Security框架会抛出异常代表用户名不存在,需要全局异常处理进行处理,如果查询到的密码和用户输入的密码一致,则不抛出异常

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHmnJqDr-1685448761188)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530200815954.png)]

  7. UserController中的login方法会执行完,给客户端响应登录成功的信息,如果登录的密码错误,Security框架会抛出代表密码错误的异常,此时也需要全局异常处理类进行处理

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L5UHfKss-1685448761190)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530201119444.png)]

教师总结

同步请求和异步请求

  • 同步: 指单线程依次做几件事
  • 异步: 指多线程同时做几件事
  • 同步请求: 指客户端浏览器只有一个主线程,主线程既要负责页面渲染\监听用户的页面操作还需要负责发请求, 当主线程发出请求时,会将页面中的内容清空,知道服务器响应了数据之后再将响应的数据展示出来, 这个过程称为页面的整体刷新, 同步请求无法实现页面的局部刷新
  • 异步请求: 指客户端浏览器由主线程负责页面渲染和监听用户的页面的操作, 由子线程负责发出请求, 当子线程请求到数据之后,可以把得到的数据显示到原页面中, 这就是页面的局部刷新.

创建SpringBoot工程

  • 工程名boot01 打3个勾
  • 在pom.xml添加以下依赖 并刷新maven
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency><!--添加Knife4j依赖-->
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version>
</dependency><!--Spring Validation依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  • 在application.properties里面添加以下配置信息
spring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
# 设置MyBatis框架的映射(Mapper)配置文件的位置
mybatis.mapper-locations=classpath:mappers/*.xmllogging.level.cn.tedu=debug

JSON

  • JSON 是一种轻量级的数据交换格式(也称为数据封装格式)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wnERl8QG-1685441210339)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530113359227.png)]

  • 当服务器给客户端响应复杂数据时需要将数据封装到Java对象里面, 但是Java对象不是跨平台的对象, 客户端是无法直接识别Java格式的对象的, 这时候就需要将Java的对象先转成JSON格式的字符串, 因为字符串是跨平台的类型, 客户端接收到JSON格式的字符串时,Axios框架会自动将其转成JS语言的对象 .

SpringSecurity框架流程

  1. 在工程中的pom.xml里面添加依赖
  2. 创建一个SecurityConfig.java配置类, 在里面重写configure方法
  3. 在方法中配置白名单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u7rLvOlq-1685441210340)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530160349272.png)]

  1. 创建UserDetailsServiceImpl实现类, 在里面配置正确的用户名和密码

​		[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hhq3m9CA-1685441210341)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530160314925.png)]

  1. 将默认的密码编码器设置为无加密

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qK6VZJUs-1685441210342)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530160234691.png)]

  1. 配置自己的登录页面

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pCHAe8HM-1685441210343)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530162523712.png)]

  2. 使用自己的登录页面时,Security框架的登录认证流程不会自动启动,需要我们在UserController处理login请求时手动开启,手动开启时需要用到认证管理器,在Security配置类中进行配置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dpuPmdUx-1685441210344)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530162856261.png)]

​ 在UserController中自动装配认证管理器对象,并在login方法中启动认证流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-By2kXrql-1685441210346)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530165425169.png)]

  1. 关闭跨域攻击防御

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1YQ4jnir-1685441210347)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530165542503.png)]

  1. UserDetailServiceImpl里面添加从数据库中查询数据的代码

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9PvV1FkN-1685441210348)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530174734134.png)]

  2. 当登录失败时Security框架抛出了两种异常,需要在全局异常处理类中添加处理方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uwkGXwFn-1685441210349)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230530174839215.png)]

Security框架认证流程:

  1. 在SecurityConfig配置类中配置好白名单, 设置登录页面, 关闭跨域攻击防御策略
  2. 当客户端请求的路径不在白名单里面, Security框架会自动将请求重定向到登录页面
  3. 在login.html登录页面中向/login地址发出登录请求时,服务器中UserController里面的login方法处理该请求
  4. 在login方法中通过认证管理器manager启动认证 将认证结果保存在Security上下文对象中
  5. 当manager启动认证流程后会自动调用UserDetailServiceImpl里面的loadUserByUsername方法, 在方法内部 调用UserMapper里面的查询方法通过用户名查询到UserVO, 如果查询不到return null, 此时Security框架会抛出异常代表用户名不存在,需要在全局异常处理中进行处理, 如果查询到的密码和用户输入的密码一致,则不会抛出任何异常 UserController中的login方法会执行完,给客户端响应登录成功的信息, 如果登录的密码错误Security框架会抛出代表密码错误的异常,此时也需要在全局异常处理类中进行处理.

http://www.ppmy.cn/news/108132.html

相关文章

Python期末复习题库(下)——“Python”

小雅兰期末加油冲冲冲&#xff01;&#xff01;&#xff01; 1. (单选题)下列关于文件打开模式的说法,错误的是( C )。 A. r代表以只读方式打开文件 B. w代表以只写方式打开文件 C. a代表以二进制形式打开文件 D. 模式中使用时,文件可读可写 2. (单选题)下列选项中,以追加…

水声声波频率如何划分?水声功率放大器可将频率放大到20MHz吗?

水声声波频率如何划分&#xff1f;水声功率放大器可将频率放大到20MHz吗&#xff1f; 现如今我们可以在地球任意地区实现通信&#xff0c;是因为电磁波的作用。但是我们都知道海洋占了全球十分之七面积&#xff0c;电磁波在水下衰减速度太快&#xff0c;无法做到远距离传输&am…

学会这两件事,让你在人生路上走得更远

人生&#xff0c;就是一场不断前行&#xff0c;没有退路的旅行&#xff0c;也是一场不断醒悟的过程。 看透&#xff0c;然后醒悟&#xff1b;放下&#xff0c;然后幸福。 有些事&#xff0c;看淡就好&#xff1b;有些人&#xff0c;看穿就行。 不管世事如何艰难&#xff0c;只要…

七人拼团系统开发模式详解

七人拼团是最近兴起的一个模式&#xff0c;它通过更人性化的奖励机制&#xff0c;将产品利润最大化让利给参与拼团的用户&#xff0c;达到促进用户主动积极裂变和团队平台引流提升销量的效果&#xff0c;下面就来详细说一下这个模式。 七人拼团最大的特点&#xff0c;就是结合了…

身份集权设施保护之Kerberos协议

一、Kerberos协议介绍 Kerberos是一种由MIT&#xff08;麻省理工大学&#xff09;提出的一种网络身份验证协议。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。该认证过程的实现不依赖于主机操作系统的认证&#xff0c;无需基于主机地址的信任&#xff0…

美食菜谱类APP小程序开发功能有哪些?

想要开发出一款靠谱好用的美食菜谱APP小程序系统&#xff0c;需要具备哪些基本功能呢&#xff1f; 1、视频教学。对于美食的教学教学方法最直接受用的就是视频教学&#xff0c;用户浏览起来更加方便而且可以直接跟着视频操作&#xff0c;效果更佳。用户也可以自己拍摄制…

使用docker安装mysql、redis、mq、es步骤记录

以下为个人参考资料安装的步骤记录&#xff0c;个别步骤可能容易迷 欢迎指出问题 cd / mkdir myfile 自己创建挂载存放的文件夹目录名称 安装 redis mysql5.7 3306端口 1.拉取镜像 docker pull mysql:5.7 2.创建容器 docker run -p 3306:3306 --name mysql5.7 \ -v /myfile/m…

DBA之路--体系结构_数据库-物理存储结构

物理存储结构数据库&#xff08;oracle数据的根本&#xff09; 数据文件类型data file&#xff0c;包含数据文件和临时文件两种&#xff0c;用于存储用户数据和应用程序数据。 在c版本中只有处于CDB$ROOT根容器才会显示全部容器的表空间&#xff0c;而处于主容器下的子容器内&a…