docs(开发日志): 补充 RSA 加密功能文档和细节调整
- 追加 RSA 密码加密传输的完整实现文档 - 操作日志相关细节调整 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c935988188
commit
6f47a07401
@ -121,3 +121,112 @@
|
||||
| `SchoolOperationLogController.java` | 字段映射 |
|
||||
| `school.ts` | 类型定义更新 |
|
||||
| `OperationLogView.vue` | 详情展示新增字段 |
|
||||
|
||||
---
|
||||
|
||||
## 工作内容 - RSA 密码加密传输实现
|
||||
|
||||
### 背景
|
||||
当前登录系统密码明文传输,存在安全风险。需要实现 RSA 非对称加密,确保密码在传输过程中加密。
|
||||
|
||||
### 实现方案
|
||||
使用简化 RSA 方案:
|
||||
1. 后端生成 RSA 密钥对,提供公钥获取接口
|
||||
2. 前端登录前获取公钥,用 RSA 加密密码
|
||||
3. 后端用私钥解密密码,继续原有登录流程
|
||||
|
||||
### 修改内容
|
||||
|
||||
#### 后端部分
|
||||
|
||||
**1. 新建 RSA 加密工具类** (`RsaEncryptionUtil.java`)
|
||||
- 生成 RSA 2048 位密钥对
|
||||
- 提供公钥获取方法
|
||||
- 提供私钥解密方法
|
||||
- 支持密钥版本管理
|
||||
- 密钥仅保存在内存中,不持久化
|
||||
|
||||
**2. 新建密钥轮换任务** (`RsaKeyRotationTask.java`)
|
||||
- 每月 1 日凌晨 2 点自动更换 RSA 密钥
|
||||
- 使用 `@Scheduled(cron = "0 0 2 1 * ?")` 定时执行
|
||||
- 支持日志记录密钥版本变更
|
||||
|
||||
**3. 新建加密登录请求 DTO** (`EncryptedLoginRequest.java`)
|
||||
- `username` - 登录账号(明文)
|
||||
- `encryptedPassword` - RSA 加密后的密码(Base64)
|
||||
- `role` - 登录角色
|
||||
- `keyVersion` - 密钥版本号(可选)
|
||||
|
||||
**4. 新建公钥响应 DTO** (`PublicKeyResponse.java`)
|
||||
- `publicKey` - RSA 公钥(Base64)
|
||||
- `keyVersion` - 当前密钥版本号
|
||||
|
||||
**5. 修改认证控制器** (`AuthController.java`)
|
||||
- 新增 `GET /api/v1/auth/public-key` - 获取 RSA 公钥
|
||||
- 新增 `POST /api/v1/auth/login/encrypted` - 加密登录接口
|
||||
- 注入 `RsaEncryptionUtil` 进行加解密操作
|
||||
|
||||
#### 前端部分
|
||||
|
||||
**6. 添加依赖** (`package.json`)
|
||||
- 添加 `jsencrypt@^3.3.2` - RSA 加密库
|
||||
|
||||
**7. 新建加密工具** (`encryption.ts`)
|
||||
- `rsaEncrypt(data, publicKey)` - RSA 加密函数
|
||||
- 导出 `PublicKeyResponse` 和 `EncryptedLoginParams` 类型
|
||||
|
||||
**8. 修改认证 API** (`auth.ts`)
|
||||
- 新增 `getPublicKey()` - 获取公钥
|
||||
- 新增 `loginEncrypted(params)` - 加密登录
|
||||
|
||||
**9. 修改用户 Store** (`user.ts`)
|
||||
- 修改 `login()` 函数,改为 RSA 加密流程:
|
||||
1. 获取 RSA 公钥
|
||||
2. 加密密码
|
||||
3. 调用加密登录接口
|
||||
|
||||
### 登录流程变更
|
||||
|
||||
**原流程**:
|
||||
```
|
||||
明文密码 → POST /api/v1/auth/login → 后端验证
|
||||
```
|
||||
|
||||
**新流程**:
|
||||
```
|
||||
1. GET /api/v1/auth/public-key → 获取 RSA 公钥
|
||||
2. 前端用公钥加密密码
|
||||
3. POST /api/v1/auth/login/encrypted → 后端私钥解密 → 验证登录
|
||||
```
|
||||
|
||||
### 安全特性
|
||||
|
||||
- RSA 2048 位加密,安全性足够
|
||||
- **密钥每月自动更换** - 每月 1 日凌晨 2 点自动更换
|
||||
- 密钥版本管理 - 便于排查问题
|
||||
- 私钥仅保存在后端内存中,不持久化
|
||||
- 必须配合 HTTPS 使用
|
||||
|
||||
### 验证步骤
|
||||
|
||||
1. 安装前端依赖:`cd reading-platform-frontend && npm install`
|
||||
2. 启动后端服务,测试 `GET /api/v1/auth/public-key` 返回公钥
|
||||
3. 启动前端,打开浏览器开发者工具
|
||||
4. 登录时检查 Network 面板:
|
||||
- `/v1/auth/public-key` 返回公钥
|
||||
- `/v1/auth/login/encrypted` 请求的 `encryptedPassword` 为密文
|
||||
5. 验证登录功能正常
|
||||
|
||||
### 文件清单
|
||||
|
||||
| 文件 | 操作 | 说明 |
|
||||
|------|------|------|
|
||||
| `RsaEncryptionUtil.java` | 新建 | RSA 加密工具类 |
|
||||
| `RsaKeyRotationTask.java` | 新建 | 密钥轮换定时任务 |
|
||||
| `EncryptedLoginRequest.java` | 新建 | 加密登录请求 DTO |
|
||||
| `PublicKeyResponse.java` | 新建 | 公钥响应 DTO |
|
||||
| `AuthController.java` | 修改 | 添加公钥和加密登录接口 |
|
||||
| `package.json` | 修改 | 添加 jsencrypt 依赖 |
|
||||
| `encryption.ts` | 新建 | 前端 RSA 加密工具 |
|
||||
| `auth.ts` | 修改 | 添加加密登录 API |
|
||||
| `user.ts` | 修改 | 使用 RSA 加密登录 |
|
||||
|
||||
@ -184,6 +184,11 @@ export function getTeacherSourceCourses() {
|
||||
return api.teacherSchoolCourseControllerGetSourceCourses() as any;
|
||||
}
|
||||
|
||||
// 获取学校端可创建校本课程包的源课程列表
|
||||
export function getSourceCourses() {
|
||||
return api.schoolCourseControllerGetSourceCourses() as any;
|
||||
}
|
||||
|
||||
// 获取教师端校本课程包详情
|
||||
export function getTeacherSchoolCourseDetail(id: number) {
|
||||
return api.teacherSchoolCourseControllerFindOne(id) as any;
|
||||
|
||||
@ -888,6 +888,9 @@ export const getOperationLogs = (params?: {
|
||||
...log,
|
||||
userType: (log as any).userRole, // 后端字段 userRole 映射为前端 userType
|
||||
description: (log as any).details, // 后端字段 details 映射为前端 description
|
||||
createdBy: (log as any).createBy, // 操作人
|
||||
requestParams: (log as any).requestParams, // 请求参数
|
||||
requestUri: (log as any).requestUri, // 请求接口
|
||||
oldValue: null, // 后端暂未支持
|
||||
newValue: null, // 后端暂未支持
|
||||
})),
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
>
|
||||
<a-descriptions :column="2" bordered size="small" v-if="selectedLog">
|
||||
<a-descriptions-item label="操作用户">
|
||||
{{ selectedLog.userType }} (ID: {{ selectedLog.userId }})
|
||||
{{ selectedLog.createdBy || selectedLog.userType }} (ID: {{ selectedLog.userId }})
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="操作时间">
|
||||
{{ formatDateTime(selectedLog.createdAt) }}
|
||||
@ -156,6 +156,9 @@ interface OperationLog {
|
||||
oldValue: string | null;
|
||||
newValue: string | null;
|
||||
ipAddress: string | null;
|
||||
createdBy?: string;
|
||||
requestParams?: string;
|
||||
requestUri?: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
@ -191,10 +194,12 @@ const pagination = reactive({
|
||||
|
||||
// 表格列
|
||||
const columns = [
|
||||
{ title: '操作人', dataIndex: 'createdBy', key: 'createdBy', width: 120 },
|
||||
{ title: '用户类型', key: 'userType', width: 100 },
|
||||
{ title: '模块', key: 'module', width: 120 },
|
||||
{ title: '操作', key: 'action', width: 120 },
|
||||
{ title: '描述', dataIndex: 'description', key: 'description', ellipsis: true },
|
||||
{ title: '请求接口', dataIndex: 'requestUri', key: 'requestUri', width: 180, ellipsis: true },
|
||||
{ title: 'IP地址', dataIndex: 'ipAddress', key: 'ipAddress', width: 130 },
|
||||
{ title: '时间', key: 'createdAt', width: 180 },
|
||||
{ title: '操作', key: 'actions', width: 80 },
|
||||
|
||||
@ -110,6 +110,7 @@ public class SchoolOperationLogController {
|
||||
.userAgent(log.getUserAgent())
|
||||
.requestParams(log.getRequestParams())
|
||||
.requestUri(log.getRequestUri())
|
||||
.createBy(log.getCreateBy())
|
||||
.createdAt(log.getCreatedAt())
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -54,6 +54,9 @@ public class OperationLogResponse {
|
||||
@Schema(description = "请求接口路径")
|
||||
private String requestUri;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String createBy;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
-- =====================================================
|
||||
-- 操作日志表添加请求接口字段
|
||||
-- 版本:V49
|
||||
-- 版本:V50
|
||||
-- 创建时间:2026-03-24
|
||||
-- 描述:在 operation_log 表中添加 request_uri 字段,用于记录请求接口路径
|
||||
-- =====================================================
|
||||
|
||||
Loading…
Reference in New Issue
Block a user