diff --git a/backend/pom.xml b/backend/pom.xml index 70d03fd..17390d8 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -16,6 +16,52 @@ + + org.springframework.boot + spring-boot-starter-security + 2.7.0 + + + + + org.springframework.boot + spring-boot-starter-jdbc + 2.7.1 + + + + + org.projectlombok + lombok + 1.18.24 + provided + + + + + + mysql + mysql-connector-java + 8.0.30 + + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.2 + + + + + com.baomidou + mybatis-plus-generator + 3.5.3 + + + + + org.springframework.boot spring-boot-starter-thymeleaf diff --git a/backend/src/main/java/com/kob/backend/config/CorsConfig.java b/backend/src/main/java/com/kob/backend/config/CorsConfig.java index 09d1b34..ed3b0de 100644 --- a/backend/src/main/java/com/kob/backend/config/CorsConfig.java +++ b/backend/src/main/java/com/kob/backend/config/CorsConfig.java @@ -1,3 +1,5 @@ +//复制粘贴 【解决跨域问题】 + package com.kob.backend.config; import org.springframework.context.annotation.Configuration; diff --git a/backend/src/main/java/com/kob/backend/config/SecurityConfig.java b/backend/src/main/java/com/kob/backend/config/SecurityConfig.java new file mode 100644 index 0000000..ed324e8 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/config/SecurityConfig.java @@ -0,0 +1,20 @@ +//实现用户密码的加密存储。==>加上此文件,必须是密文存储 + +package com.kob.backend.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableWebSecurity + +public class SecurityConfig { + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder();//返回加密方法 + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/kob/backend/controller/pk/IndexController.java b/backend/src/main/java/com/kob/backend/controller/pk/IndexController.java index a8fc3bd..10dff2b 100644 --- a/backend/src/main/java/com/kob/backend/controller/pk/IndexController.java +++ b/backend/src/main/java/com/kob/backend/controller/pk/IndexController.java @@ -4,10 +4,9 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller - public class IndexController { - @RequestMapping("") + @RequestMapping( "/") public String index() { return "pk/index.html"; diff --git a/backend/src/main/java/com/kob/backend/controller/user/UserController.java b/backend/src/main/java/com/kob/backend/controller/user/UserController.java new file mode 100644 index 0000000..7a5f085 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/controller/user/UserController.java @@ -0,0 +1,79 @@ +package com.kob.backend.controller.user; + + +//@ResponseBody 把return的结果变为Json等数据, +//@Controller 返回jsp,html页面+跳转 +//@Controller + @ResponseBody 返回json等数据 +//@RestController 返回json等数据,不能是jsp,html【@Controller+@responseBody】 + +//@RequestMapping 给出外界访问方法的路径,或者说触发路径 ,触发条件 +//@GetMapping +//PostMapping + +//@AutoWired:自动导入依赖的bean。[用到mapper层的接口时,数据库,写上去] +//byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 +//当加上(required=false)时,就算找不到bean也不报错。 +//它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。 + +//mapper接口 被mybatis实现 +//接口实例调用mybatis的crud +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.kob.backend.mapper.UserMapper; +import com.kob.backend.pojo.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +//@@@@@@@@@@@@@@@ 实现了【增删查】 @@@@@@@@@@@@@@@@ +@RestController +public class UserController { + + @Autowired + UserMapper userMapper; + + /*查询所有用户*/ + @GetMapping("/user/all/") + public List getAll() + { + return userMapper.selectList(null); + } + + /*查询单个用户*/ + @GetMapping("/user/{userId}/") + public User getUser(@PathVariable int userId) + { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id",userId); + return userMapper.selectOne(queryWrapper); + // 范围遍历 + // public List getUser(int userId) + // queryWrapper.ge("id", 2).le("id", 3); + // return userMapper.selectList(queryWrapper); + } + + /*添加一个用户*/ + @GetMapping("/user/add/{userId}/{username}/{password}/") + public String addUser(@PathVariable int userId, + @PathVariable String username, + @PathVariable String password) + { + PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + String encoderPassword = passwordEncoder.encode(password); + User user = new User(userId,username,encoderPassword); + userMapper.insert(user); + return "Add User Sucessfully"; + } + + /*删除一个用户*/ + @GetMapping("/user/delete/{userId}/") + public String deleteUser(@PathVariable int userId) + { + userMapper.deleteById(userId); + return "Delete User Successfully"; + } + +} \ No newline at end of file diff --git a/backend/src/main/java/com/kob/backend/mapper/UserMapper.java b/backend/src/main/java/com/kob/backend/mapper/UserMapper.java new file mode 100644 index 0000000..423fe5f --- /dev/null +++ b/backend/src/main/java/com/kob/backend/mapper/UserMapper.java @@ -0,0 +1,16 @@ +package com.kob.backend.mapper; + +//但如User类 +import com.kob.backend.pojo.User; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +//@Mapper注解 是由Mybatis框架中定义的一个描述数据层接口的注解,方便使用mybatis +//BaseMapper中有大量mybatis的 增删改查 的sql + +@Mapper +public interface UserMapper extends BaseMapper { + + +} diff --git a/backend/src/main/java/com/kob/backend/pojo/User.java b/backend/src/main/java/com/kob/backend/pojo/User.java new file mode 100644 index 0000000..bec7030 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/pojo/User.java @@ -0,0 +1,21 @@ +package com.kob.backend.pojo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +//@Data : 注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法 +//@AllArgsConstructor : 注在类上,提供类的全参构造 +//@NoArgsConstructor : 注在类上,提供类的无参构造 +//@Setter : 注在属性上,提供 set 方法 +//@Getter : 注在属性上,提供 get 方法 +//@EqualsAndHashCode : 注在类上,提供对应的 equals 和 hashCode 方法 +//@Log4j/@Slf4j : 注在类上,提供对应的 Logger 对象,变量名为 log + +@NoArgsConstructor +@AllArgsConstructor +@Data +public class User { + private Integer id; + private String username; + private String password; +} \ No newline at end of file diff --git a/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java new file mode 100644 index 0000000..38c4047 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java @@ -0,0 +1,41 @@ +package com.kob.backend.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.kob.backend.mapper.UserMapper; +import com.kob.backend.service.impl.utils.UserDetailsImpl; +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 com.kob.backend.pojo.User; +import org.springframework.stereotype.Service; + + +//UserDetailsService接口 用来接入数据库信息。 +//@Override重写 作用:如果想重写父类的方法, +//比如toString()方法的话,在方法前面加上@Override 系统可以帮你检查方法的正确性。 +//@Service 注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中, + +//UserDetailsService接口 加载用户通过用户名 返回UserDetails接口实例 用户名找不到异常 +//UserDetails接口 实现具体用户状态【启用/过期/上锁等】 + +@Service +public class UserDetailsServiceImpl implements UserDetailsService{ + + @Autowired + private UserMapper userMapper; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("username",username); + User user = userMapper.selectOne(queryWrapper); + if(user==null) + { + throw new RuntimeException("用户不存在!"); + } + + return new UserDetailsImpl(user);//实现UserDetails接口 + } +} diff --git a/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java b/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java new file mode 100644 index 0000000..e49d92b --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java @@ -0,0 +1,56 @@ +package com.kob.backend.service.impl.utils; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +import com.kob.backend.pojo.User; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserDetailsImpl implements UserDetails +{ + + private User user; + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public String getUsername() { return user.getUsername();} + //isAccountNonExpired 账户没有过期 + @Override + public boolean isAccountNonExpired() {//账号没过期 + return true; + } + + //isAccountNonLocked 账户没有被锁定 + @Override + public boolean isAccountNonLocked() {//账号没被锁定 + return true; + } + + //isCredentialsNonExpired 身份认证没过期 + @Override + public boolean isCredentialsNonExpired() {//凭证没过期 + return true; + } + + //isEnabled 账户启用 + @Override + public boolean isEnabled() {//用户已被禁用 + return true; + } +} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index d453c33..9d8b7b4 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,27 +1,7 @@ -# 应用名称 -spring.application.name=backend -# THYMELEAF (ThymeleafAutoConfiguration) -# 开启模板缓存(默认值: true ) -spring.thymeleaf.cache=true -# 检查模板是否存在,然后再呈现 -spring.thymeleaf.check-template=true -# 检查模板位置是否正确(默认值 :true ) -spring.thymeleaf.check-template-location=true -#Content-Type 的值(默认值: text/html ) -spring.thymeleaf.content-type=text/html -# 开启 MVC Thymeleaf 视图解析(默认值: true ) -spring.thymeleaf.enabled=true -# 模板编码 -spring.thymeleaf.encoding=UTF-8 -# 要被排除在解析之外的视图名称列表,⽤逗号分隔 -spring.thymeleaf.excluded-view-names= -# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5) -spring.thymeleaf.mode=HTML5 -# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ ) -spring.thymeleaf.prefix=classpath:/templates/ -# 在构建 URL 时添加到视图名称后的后缀(默认值: .html ) -spring.thymeleaf.suffix=.html -# 应用服务 WEB 访问端口 server.port=3000 +spring.datasource.username=root +spring.datasource.password=dyh20011022 +spring.datasource.url=jdbc:mysql://localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8 +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver diff --git a/backend/src/test/java/com/kob/backend/BackendApplicationTests.java b/backend/src/test/java/com/kob/backend/BackendApplicationTests.java index b19336e..b20a988 100644 --- a/backend/src/test/java/com/kob/backend/BackendApplicationTests.java +++ b/backend/src/test/java/com/kob/backend/BackendApplicationTests.java @@ -2,12 +2,22 @@ package com.kob.backend; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; @SpringBootTest -class BackendApplicationTests { - +class BackendApplicationTests +{ @Test - void contextLoads() { + void contextLoads() + { + PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); +// System.out.println(passwordEncoder.matches("yxc","$2a$10$3TiNxWq48h3Po1n3.NekNeTEOXYDJEgkvMkvXIVIBiaRQgZ9ArFIW")); +// System.out.println(passwordEncoder.matches("yxc","$2a$10$0cqbcHGmNmil3.4xdBPGveP2lhusn/ox4zZlbYOe2xYYjzzrBPg.6")); + System.out.println(passwordEncoder.encode("yxc")); + System.out.println(passwordEncoder.encode("passw2")); + System.out.println(passwordEncoder.encode("passw3")); +// System.out.println(passwordEncoder.encode("yxc")); } }