auth-server-java/ReadMe.md

563 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Github地址
- [前端地址](https://github.com/BunnyMaster/bunny-admin-web.git)
- [后端地址](https://github.com/BunnyMaster/bunny-admin-server)
Gitee地址
- [前端地址](https://gitee.com/BunnyBoss/bunny-admin-web)
- [后端地址](https://gitee.com/BunnyBoss/bunny-admin-server)
# 搭建后端环境
1. 需要JDK17
2. MySQL
3. Redis
4. Minio
## 下载JDK17
不喜欢JDK17可以自己将版本修改
官网https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
## 资料相关
### Docker配置
配置的端口号是8000根据自己需求进行更改当然这些配置都可以修改但是`"/www/root/server"`这个不能改,除非不需要动态修改配置文件
- 如果需要访问内部docker或者有这种需求访问宿主机docker需要配置下面三个文件这三个文件需要对应你的宿主机上的位置下面展示的三个是服务容器中的地址之后需要使用docker命令绑定映射这几个文件夹位置即可。
``` dockerfile
VOLUME /usr/bin/docker
VOLUME ["/var/run/docker.sock"]
VOLUME /etc/docker/daemon.json
VOLUME ["/www/root/backup"]
VOLUME ["/www/root/server"]
```
- 备份资源和基础路径设置,如果是需要备份数据库,比如你的数据库就在本机那么可以使用这个文件夹,之后需要映射这个数据卷
```dockerfile
VOLUME ["/www/root/backup"]
```
- 基础路径比如需要设置前端配置文件的因为第一次启动项目肯定是没有这个配置文件而且打成jar包之后是不可以修改resource下资源的需要将资源放到外面目录中
- 如果以后更新了服务那么docker容器内容会被清空比如备份的资源或者是配置的资源又要重新配置这个地址挂载到数据卷中之后就可以映射即使项目更新等文件也要只要不把宿主机文件删除就可以。
```dockerfile
VOLUME ["/www/root/server"]
```
![image-20241023094711026](http://116.196.101.14:9000/docs/image-20241023094711026.png)
### 部署命令
仅供参考,实际的需要替换成你自己宿主机中的地址。
```bash
docker run -p 8000:8000 \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/docker/daemon.json:/etc/docker/daemon.json \
-v /bunny/docker_data/mysql/slave_3304/backup:/www/root/backup \
-v /bunny/docker_data/server:/www/root/server \
--name bunny_auth_server --restart always bunny_auth_server:1.0.0
```
### 代码生成器
生成简单CURD后端文件和前端CURD页面使用`velocity`
![image-20241023091904775](http://116.196.101.14:9000/docs/image-20241023091904775.png)
### 后端相关文件
直接导入
![image-20241023091610302](http://116.196.101.14:9000/docs/image-20241023091610302.png)
### 前端文件
有data.js可以生成权限相关内容只是简单的生成
![image-20241028224835163](http://116.196.101.14:9000/docs/image-20241028224835163.png)
## 搭建MySQL
使用docker开发环境端口号为3304生产环境为3306
数据使用不区分大小写因为涉及到quartz但是quartz默认数据库名称包括表名都是大写的我不喜欢所以就设置了此项。
MySQL中设置了唯一约束字段详见MySQL文件
### 生产环境MySQL搭建
- 将之前的MySQL移除名称为master【确保你的master没有或者不重要以防不小心删除重要数据】
```shell
docker stop master
docker rm master
docker run --name master -p 3306:3306 \
-v /bunny/docker_data/mysql/master/etc/my.cnf:/etc/my.cnf \
-v /bunny/docker_data/mysql/master/data:/var/lib/mysql \
--restart=always --privileged=true \
-e MYSQL_ROOT_PASSWORD=02120212 \
-e TZ=Asia/Shanghai \
mysql:8.0.33 --lower-case-table-names=1
```
### 开发环境搭建
```shell
docker stop slave_3304
docker rm slave_3304
docker run --name slave_3304 -p 3304:3306 \
-v /bunny/docker_data/mysql/slave_3304/etc/my.cnf:/etc/my.cnf \
-v /bunny/docker_data/mysql/slave_3304/data:/var/lib/mysql \
-v /bunny/docker_data/mysql/slave_3304/backup:\
--restart=always --privileged=true \
-e MYSQL_ROOT_PASSWORD=02120212 \
-e TZ=Asia/Shanghai \
mysql:8.0.33 --lower-case-table-names=1
```
### 修改密码
```shell
docker exec -it mysql_master /bin/bash
mysql -uroot -p02120212
use mysql
ALTER USER 'root'@'%' IDENTIFIED BY "02120212";
FLUSH PRIVILEGES;
```
### my.cnf 配置
```shell
[mysqld]
skip-host-cache
skip-name-resolve
secure-file-priv=/var/lib/mysql-files
user=mysql
# 设置字符集
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 设置服务器ID如果是复制集群确保每个节点的ID唯一
server-id=1
# 启用二进制日志
log-bin=mysql-bin
# 设置表名不区分大小写
lower_case_table_names = 1
```
## 安装Redis
### 配置文件
```
daemonize no
requirepass 123456
appendonly yes
tcp-keepalive 300
```
### 运行Redis
```shell
docker pull redis:7.0.10
docker run -p 6379:6379 --name redis_master \
-v /bunny/docker_data/redis_master/redis.conf:/etc/redis/redis.conf \
-v/bunny/docker_data/redis_master/data:/data \
--restart=always -d redis:7.0.10 --appendonly yes
```
## 安装Minio
```sh
docker run -d \
-p 9000:9000 \
-p 9090:9090 \
--name minio_master --restart=always \
-v /bunny/docker/minio/data:/data \
-e "MINIO_ROOT_USER=bunny" \
-e "MINIO_ROOT_PASSWORD=02120212" \
minio/minio server /data --console-address ":9090"
```
# 接口说明
为了方便开发,这个功能已经测试过了,也是为了线上能看到效果,邮箱验证码后端验证部分已经注释
## 请求接口
请求接口都是`/admin`前缀,部分接口会被忽略,忽略接口看下面。
所有分页请求内容都是通过路径传参方式
请求时需要带有token只要前端在请求头中添加`token:内容`即可
采用SpringSecurity验证
## 接口忽略
### SpringSecurity接口忽略
这是相关拦截请求内容如果要访问接口必须携带token但是有些接口是不需要token的不需要token就配置在这里。但是放在这里后如果用户请求的地址是被忽略的那么也就拿不到token也就拿不到登录相关信息。
获取用户自身的登录请求是不需要携带用户Id只要有token去解析即可。
```java
// 排出鉴定路径
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
String[] annotations = {
"/", "/ws/**",
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "swagger-ui/**",
"/*/files/**",
"/error", "/*/i18n/getI18n",
};
return web -> web.ignoring().requestMatchers(annotations)
.requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$"));
}
```
![image-20241022095731221](http://116.196.101.14:9000/docs/image-20241022095731221.png)
有些会被忽略的接口,凡是带有`noAuth`都是不需要验证的,但是要注意一点,不需要验证但是后端需要拿到登录相关信息是拿不到的。
![image-20241022095311658](http://116.196.101.14:9000/docs/image-20241022095311658.png)
我是将用户相关请求使用SpringSecurity进行拦截如果有相关匹配路径那么就会被拦截此时接口参数中会带有token内容拿到token进行解析之后取出相关用户信息比如用户Id、username等。
将这些信息拿出来后放到ThreadLocal中存储在线程中如果微服务中需要需要放在请求头中因为微服务不在同一个线程中。这个操作适合单体或者是微服务中不需要请求其它微服务的方式。
![image-20241022095641040](http://116.196.101.14:9000/docs/image-20241022095641040.png)
### 不需要管理接口
请求是会有不需要登录就能访问的接口,也需要不要被管理的接口
## 验证码验证忽略
为了公网上的展示,如果需要获取验证码比较的麻烦,如果你的需求和我一样那么可以在这里放开这些注释
会判断用户登录请求的类型是什么,如果是验证码登录会判断邮箱等内容
![image-20241028224550702](http://116.196.101.14:9000/docs/image-20241028224550702.png)
![image-20241028224625149](http://116.196.101.14:9000/docs/image-20241028224625149.png)
# 功能介绍
系统使用的是物理删除但是引用了逻辑删除使用mybatisPlus如果需要逻辑删除只需要将原先删除方法调用成mybatisplus自身的删除方法即可。
作为权限管理系统校验功能已经路由功能都是由后端完成后端使用SpringSecurity
系统权限功能使用RBAC模型
## 系统设置
### 系统菜单
当用户登录时会根据,当前角色获取自身的菜单路由,防止返回不该返回的页面,之后权限和角色关联,根据用户权限查询可以访问的菜单内容,如果权限中没有这个路径那么会告知`无权访问`。
管理员需要在配置时,配置菜单和角色之间的关系,用户也要和角色关联,角色会关联权限表,返回路由时只返回当前用户可以访问的菜单。
- 前端做递归,排序后端也做了
- 快捷排序,快捷禁用菜单
- 路由菜单图标需要再系统配置中添加菜单图标
![image-20241023090359575](http://116.196.101.14:9000/docs/image-20241023090359575.png)
#### 菜单分配角色
![image-20241023090640516](data/images/image-20241023090640516.png)
其中有快捷清除菜单中所有的角色还有批量分配菜单角色
![image-20241028223214756](http://116.196.101.14:9000/docs/image-20241028223214756.png)
#### 批量分配角色
批量分配角色并不会在原有的基础上追加角色,会清除原有的角色内容,一般用于初始化菜单
![image-20241028223311365](http://116.196.101.14:9000/docs/image-20241028223311365.png)
#### 一键清除菜单角色
会有两次确认,如果确认会清除菜单下所有的角色内容
![image-20241028223401638](http://116.196.101.14:9000/docs/image-20241028223401638.png)
### 用户管理
强制下线就是将Redis中用户信息删除
用户禁用先改数据库之后将Redis中数据进行删除
![image-20241023091239212](data/images/image-20241023091239212.png)
#### 关于用户管理事务问题
如果用户禁用失败或者删除Redis失败需要回滚事务在Spring中有集成的事务只需要简单的配置下即可
![image-20241028223455906](http://116.196.101.14:9000/docs/image-20241028223455906.png)
### 角色管理
如果为角色重新分配权限确认后系统会找到这些角色所分配的用户之后更新Redis内容前端刷新后就可以看到更新过的角色内容
![image-20241023091310533](http://116.196.101.14:9000/docs/image-20241023091310533.png)
### 权限管理
权限管理可以设置父级内容,在前端文件中有`data.js`,可以自动生成权限相关内容。
如果重新分配好权限后不会刷新Redis相关内容
![image-20241023091328271](http://116.196.101.14:9000/docs/image-20241023091328271.png)
**前端文件**
前端文件只需要修改用户token就可以为数据库中批量添加权限一般用于初始化数据时使用
![image-20241023091503966](http://116.196.101.14:9000/docs/image-20241023091503966.png)
![image-20241028223737014](http://116.196.101.14:9000/docs/image-20241028223737014.png)
### 部门管理
如果原先用户被删除不会清除部门中的管理员信息
![image-20241023092027273](http://116.196.101.14:9000/docs/image-20241023092027273.png)
## 系统配置
### 菜单图标
![image-20241023092123926](http://116.196.101.14:9000/docs/image-20241023092123926.png)
### 邮件用户配置
发送邮件时,如果没有选定用户会去找默认用户
邮箱需要唯一不可重复
![image-20241023092145274](http://116.196.101.14:9000/docs/image-20241023092145274.png)
### 邮件模板
模板名称需要唯一不可重复
![image-20241023092250382](http://116.196.101.14:9000/docs/image-20241023092250382.png)
#### 模板类型说明
根据后端的枚举类进行返回
![image-20241023092355799](http://116.196.101.14:9000/docs/image-20241023092355799.png)
后端文件,枚举信息在这
![image-20241023092439168](data/images/image-20241023092439168.png)
## 系统监控
### 服务监控
服务监控来自springboot中actuator框架每隔两秒刷新一次
![image-20241028223955087](http://116.196.101.14:9000/docs/image-20241028223955087.png)
IDEA中也有集成只要使用了actuator包即可看到服务内容、健康检查等
详细参考官网API当然如果需要后台服监控页面德国工程师帮我们写了一个页面。
![image-20241023092652996](http://116.196.101.14:9000/docs/image-20241023092652996.png)
也可以看到当前的请求API有哪些
![image-20241023093159928](http://116.196.101.14:9000/docs/image-20241023093159928.png)
#### 相关admin服务包
或许在有些服务中不需要这个页面,有服务监控的功能,配置也简单,我之前我使用在这个项目中,和部分业务功能有些冲突,与其这样不如自己写个简单的也可以
```xml
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>3.2.3</version>
</dependency>
</dependencies>
```
### 后台文件管理
用户上传的文件和头像内容都在这里文件存储位置在Minio中
![image-20241023093247261](http://116.196.101.14:9000/docs/image-20241023093247261.png)
### 用户登录日志
![image-20241028224123703](http://116.196.101.14:9000/docs/image-20241028224123703.png)
### 任务执行日志
当前设定的定时任务有关目前有数据库备份和简单的定时任务示例内容都在这使用JS对象可视化数据多时会有些卡顿
![image-20241023093407627](http://116.196.101.14:9000/docs/image-20241023093407627.png)
## 定时任务
### 调度任务
其实就是定时任务集成框架quartz持久化存储任务
![image-20241023093546293](http://116.196.101.14:9000/docs/image-20241023093546293.png)
### 任务调度分组
![image-20241023093602223](http://116.196.101.14:9000/docs/image-20241023093602223.png)
## 多语言管理
### 多语言
![image-20241023093639866](http://116.196.101.14:9000/docs/image-20241023093639866.png)
### 多语言类型
如果以后还需要其它语言可以在这个地方添加
![image-20241023093654135](http://116.196.101.14:9000/docs/image-20241023093654135.png)
## 其它功能
![image-20241023093729543](http://116.196.101.14:9000/docs/image-20241023093729543.png)
### 账户设置
更新账户信息后会更新Redis中的内容如果修改密码修改完成后会重新跳转到登录页要求重新登录
![image-20241023093749870](http://116.196.101.14:9000/docs/image-20241023093749870.png)
![image-20241023093759347](http://116.196.101.14:9000/docs/image-20241023093759347.png)
![image-20241023093807425](http://116.196.101.14:9000/docs/image-20241023093807425.png)
### 数据库事务
数据库事务在Springboot中只需要一个注解通常我们还需要redis事务在Redis中配置开启即可。
![image-20241023094104297](http://116.196.101.14:9000/docs/image-20241023094104297.png)
### 去除字符串空格
在项目中会统一进行空白字符串去除配置项也在config文件夹下
![image-20241023094247311](http://116.196.101.14:9000/docs/image-20241023094247311.png)
> 更多配置看这里
>
> ![image-20241023094311326](http://116.196.101.14:9000/docs/image-20241023094311326.png)
# 动态定时任务
使用`Quartz `数据存储在数据库中持久化存储.
所有的Quartz内容都放在这个目录中因为前端需要知道有哪些定时任务这时候又不能将数据添加到数据库中如果以后需要更多的定时任务那么需要再数据库中添加这样做很麻烦。
我们可以通过反射只要约定好内容,通过反射扫描的方式来获取这些可以使用的定时任务,反射的注解是这个:`@QuartzSchedulers(type = "test", description = "JobHello任务内容")`
![image-20241022101534393](http://116.196.101.14:9000/docs/image-20241022101534393.png)
## 注解说明
扫描注解包,可以通过依赖注入的方式使用
![image-20241022102210149](./data/images/image-20241022102210149.png)
类型注解存放位置在下面。
![image-20241022101742586](http://116.196.101.14:9000/docs/image-20241022101742586.png)
获取所有可用定时任务
![image-20241022102510646](http://116.196.101.14:9000/docs/image-20241022102510646.png)
# Quartz 方法
## TriggerBuilder
`TriggerBuilder` 是一个用于构建 `Trigger` 实例的类。它提供了一系列方法来设置触发器的各种属性。以下是一些常用的方法:
1. `withIdentity(String name, String group)``withIdentity(TriggerKey triggerKey)`:设置触发器的名称和组名。
2. `startAt(Date startTime)`:设置触发器首次触发的时间。
3. `endAt(Date endTime)`:设置触发器最后一次触发的时间。
4. `withSchedule(ScheduleBuilder scheduleBuilder)`:设置触发器的调度计划,可以是简单重复、按日历重复等。
5. `forJob(JobKey jobKey)``forJob(String jobName, String jobGroup)`指定触发器关联的作业Job
6. `usingJobData(String key, String value)`:为触发器添加自定义数据。
7. `modifiedByCalendar(String calName)`:指定一个日历,用于修改触发器的触发时间。
8. `build()`:构建并返回最终的 `Trigger` 实例。
9. `withDescription(String description)`:为触发器设置描述信息。
10. `usingJobData(JobDataMap jobData)`:使用 `JobDataMap` 为触发器设置多个作业数据。
11. `withPriority(int priority)`:设置触发器的优先级。
12. `replaceTriggerKey(TriggerKey oldKey, TriggerKey newKey)`:替换触发器的键值。
## JobBuilder
`JobBuilder` 类用于构建 `JobDetail` 实例它定义了要执行的作业Job的属性。以下是一些常用的方法
1. `withIdentity(String name, String group)``withIdentity(JobKey jobKey)`:设置作业的名称和组名。
2. `storeDurably()`:当作业没有触发器时,仍然允许作业被存储。这对于持久作业(即不被触发器触发,但可以手动调度的作业)很有用。
3. `requestRecovery()`指示Quartz在作业执行失败或调度器重启时尝试恢复作业。
4. `usingJobData(JobDataMap jobData)`:为作业添加自定义数据。
5. `usingJobData(String key, String value)`:为作业添加单个自定义数据。
6. `ofType(Class<? extends Job> jobClass)`:指定作业的类型(实现 `Job` 接口的类)。
7. `build()`:构建并返回最终的 `JobDetail` 实例。
8. `withDescription(String description)`:为作业设置描述信息。
9. `usingJobData(JobDataMap jobData, boolean merge)`:添加自定义数据,并指定是否与现有的 `JobDataMap` 合并。
10. `build()`:构建并返回最终的 `JobDetail` 实例。
# 展望未来
1. 计划将文件上传服务改为本地的OSSMinio可能会被移除。
2. 消息服务,管理员相关的消息公告内容