补充密码加密传输前后端实施计划
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
# 系统登录与密码类接口加密传输计划实施记录
|
||||||
|
|
||||||
|
## 实施时间
|
||||||
|
- 2026-03-30
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
- 新增密码加密传输后端实施计划
|
||||||
|
- 新增密码加密传输前端实施计划
|
||||||
|
- 明确后端以统一解密服务 + 控制器显式接入的方式实施
|
||||||
|
- 明确前端以统一加密工具 + API 层字段映射的方式实施
|
||||||
|
- 明确测试命令、实施记录与提交节点
|
||||||
|
|
||||||
|
## 文档路径
|
||||||
|
- `docs/superpowers/plans/2026-03-30-login-password-encryption-backend-plan.md`
|
||||||
|
- `docs/superpowers/plans/2026-03-30-login-password-encryption-frontend-plan.md`
|
||||||
|
- `doc/implementation-report-2026-03-30-login-password-encryption-plans.md`
|
||||||
|
|
||||||
|
## 计划结论
|
||||||
|
- 计划已按仓库要求拆分为后端执行文档和前端执行文档
|
||||||
|
- 两份计划都采用最短路径实现,不引入明密文兼容分支
|
||||||
|
- 后端计划覆盖统一解密、控制器接入和 MockMvc/单测验证
|
||||||
|
- 前端计划覆盖统一加密、API 接入、环境配置和 Node 脚本验证
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
- 已按要求检查计划文档保存路径,计划保存至 `docs/superpowers/plans`
|
||||||
|
- 仓库约束禁止启用 subagent,本次计划复审采用本地自检方式处理
|
||||||
|
- 当前仅完成计划文档,不包含代码实现
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
# Backend Password Transfer Encryption Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** 为正式密码提交接口补上后端解密链路,让 `/login`、`/register`、`/system/user/profile/updatePwd`、`/system/user/resetPwd`、`/system/user` 在收到密文密码后先解密,再复用现有认证与 BCrypt 逻辑。
|
||||||
|
|
||||||
|
**Architecture:** 在 `ruoyi-framework` 新增统一的密码传输解密服务,固定密钥从配置读取,负责 AES/Base64 解密和失败抛错。`ruoyi-admin` 各控制器在进入现有业务逻辑前显式调用该服务对密码字段解密,`/login/test` 保持不变。
|
||||||
|
|
||||||
|
**Tech Stack:** Spring Boot 3.5、JUnit 5、MockMvc、JDK `javax.crypto`、Maven Surefire
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: 搭建后端密码解密基础设施
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PasswordTransferCryptoService.java`
|
||||||
|
- Create: `ruoyi-framework/src/test/java/com/ruoyi/framework/web/service/PasswordTransferCryptoServiceTest.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/application.yml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/application-dev.yml`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 写解密服务失败用例**
|
||||||
|
|
||||||
|
```java
|
||||||
|
class PasswordTransferCryptoServiceTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
void shouldDecryptValidCipherText()
|
||||||
|
{
|
||||||
|
String plain = service.decrypt("Base64密文");
|
||||||
|
assertEquals("admin123", plain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRejectInvalidCipherText()
|
||||||
|
{
|
||||||
|
assertThrows(ServiceException.class, () -> service.decrypt("not-base64"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认当前失败**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-framework -am -Dtest=PasswordTransferCryptoServiceTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: FAIL,提示测试类或 `PasswordTransferCryptoService` 不存在
|
||||||
|
|
||||||
|
- [ ] **Step 3: 补配置与最小实现**
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class PasswordTransferCryptoService
|
||||||
|
{
|
||||||
|
@Value("${security.password-transfer.key}")
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
public String decrypt(String cipherText)
|
||||||
|
{
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"));
|
||||||
|
return new String(cipher.doFinal(Base64.getDecoder().decode(cipherText)), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
security:
|
||||||
|
password-transfer:
|
||||||
|
key: "请替换为16位固定密钥"
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行基础测试**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-framework -am -Dtest=PasswordTransferCryptoServiceTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/PasswordTransferCryptoService.java ruoyi-framework/src/test/java/com/ruoyi/framework/web/service/PasswordTransferCryptoServiceTest.java ruoyi-admin/src/main/resources/application.yml ruoyi-admin/src/main/resources/application-dev.yml
|
||||||
|
git commit -m "新增密码传输解密服务"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 2: 接入登录与注册接口解密
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java`
|
||||||
|
- Create: `ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysLoginControllerPasswordTransferTest.java`
|
||||||
|
- Create: `ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysRegisterControllerPasswordTransferTest.java`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 写登录与注册控制器失败测试**
|
||||||
|
|
||||||
|
```java
|
||||||
|
mockMvc.perform(post("/login")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("{\"username\":\"admin\",\"password\":\"cipher\",\"code\":\"1\",\"uuid\":\"u\"}"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
verify(passwordTransferCryptoService).decrypt("cipher");
|
||||||
|
verify(loginService).login("admin", "admin123", "1", "u");
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
mockMvc.perform(post("/register")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("{\"username\":\"u1\",\"password\":\"cipher\",\"code\":\"1\",\"uuid\":\"u\"}"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
verify(passwordTransferCryptoService).decrypt("cipher");
|
||||||
|
verify(registerService).register(any(RegisterBody.class));
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行登录/注册测试确认失败**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin -am -Dtest=SysLoginControllerPasswordTransferTest,SysRegisterControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: FAIL,控制器尚未调用解密服务
|
||||||
|
|
||||||
|
- [ ] **Step 3: 在正式接口入口补解密**
|
||||||
|
|
||||||
|
```java
|
||||||
|
loginBody.setPassword(passwordTransferCryptoService.decrypt(loginBody.getPassword()));
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
user.setPassword(passwordTransferCryptoService.decrypt(user.getPassword()));
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
- 只改 `/login`
|
||||||
|
- 不改 `loginWithoutCaptcha`
|
||||||
|
- 解密失败直接抛错,不追加明文兼容分支
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行登录/注册测试**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin -am -Dtest=SysLoginControllerPasswordTransferTest,SysRegisterControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysLoginControllerPasswordTransferTest.java ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysRegisterControllerPasswordTransferTest.java
|
||||||
|
git commit -m "接入登录注册密码解密"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 3: 接入个人修改密码接口解密
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java`
|
||||||
|
- Create: `ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysProfileControllerPasswordTransferTest.java`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 写修改密码失败测试**
|
||||||
|
|
||||||
|
```java
|
||||||
|
mockMvc.perform(put("/system/user/profile/updatePwd")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("{\"oldPassword\":\"oldCipher\",\"newPassword\":\"newCipher\"}"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
verify(passwordTransferCryptoService).decrypt("oldCipher");
|
||||||
|
verify(passwordTransferCryptoService).decrypt("newCipher");
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认失败**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin -am -Dtest=SysProfileControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: FAIL,`updatePwd` 尚未解密 `oldPassword`、`newPassword`
|
||||||
|
|
||||||
|
- [ ] **Step 3: 在 `updatePwd` 开头显式解密两个字段**
|
||||||
|
|
||||||
|
```java
|
||||||
|
String oldPassword = passwordTransferCryptoService.decrypt(params.get("oldPassword"));
|
||||||
|
String newPassword = passwordTransferCryptoService.decrypt(params.get("newPassword"));
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
- 仅在解密成功后继续旧密码校验
|
||||||
|
- 不处理 `confirmPassword`
|
||||||
|
- 保持原有报错文案和 BCrypt 入库逻辑
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行测试**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin -am -Dtest=SysProfileControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysProfileControllerPasswordTransferTest.java
|
||||||
|
git commit -m "接入个人修改密码解密"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 4: 接入管理员新增用户与重置密码接口解密
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java`
|
||||||
|
- Create: `ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysUserControllerPasswordTransferTest.java`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 写新增用户与重置密码失败测试**
|
||||||
|
|
||||||
|
```java
|
||||||
|
mockMvc.perform(post("/system/user")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("{\"userName\":\"u1\",\"nickName\":\"n1\",\"deptId\":1,\"password\":\"cipher\"}"));
|
||||||
|
|
||||||
|
verify(passwordTransferCryptoService).decrypt("cipher");
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
mockMvc.perform(put("/system/user/resetPwd")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("{\"userId\":2,\"password\":\"cipher\"}"));
|
||||||
|
|
||||||
|
verify(passwordTransferCryptoService).decrypt("cipher");
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认失败**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin -am -Dtest=SysUserControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: FAIL,新增用户和重置密码入口尚未调用解密
|
||||||
|
|
||||||
|
- [ ] **Step 3: 在 `add` 与 `resetPwd` 中先解密后继续原逻辑**
|
||||||
|
|
||||||
|
```java
|
||||||
|
user.setPassword(passwordTransferCryptoService.decrypt(user.getPassword()));
|
||||||
|
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
- 仅对 `add`、`resetPwd` 补解密
|
||||||
|
- `edit` 不动
|
||||||
|
- 仍保留现有权限校验与数据范围校验
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行测试**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin -am -Dtest=SysUserControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java ruoyi-admin/src/test/java/com/ruoyi/web/controller/system/SysUserControllerPasswordTransferTest.java
|
||||||
|
git commit -m "接入用户密码接口解密"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 5: 汇总验证与后端实施记录
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `doc/implementation-report-2026-03-30-login-password-encryption-backend.md`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 运行后端全部目标测试**
|
||||||
|
|
||||||
|
Run: `mvn -pl ruoyi-admin,ruoyi-framework -am -Dtest=PasswordTransferCryptoServiceTest,SysLoginControllerPasswordTransferTest,SysRegisterControllerPasswordTransferTest,SysProfileControllerPasswordTransferTest,SysUserControllerPasswordTransferTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||||
|
Expected: PASS,所有新增后端测试通过
|
||||||
|
|
||||||
|
- [ ] **Step 2: 手工核对 `/login/test` 未被改动**
|
||||||
|
|
||||||
|
Run: `git diff -- ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java`
|
||||||
|
Expected: 仅 `/login` 增加解密调用,`loginWithoutCaptcha` 无行为变化
|
||||||
|
|
||||||
|
- [ ] **Step 3: 写后端实施记录**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# 密码加密传输后端实施记录
|
||||||
|
- 新增密码解密服务
|
||||||
|
- 接入 5 个正式接口中的后端入口
|
||||||
|
- 保持 `/login/test` 不变
|
||||||
|
- 补充控制器与服务测试
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: 再次检查文档路径与 git 状态**
|
||||||
|
|
||||||
|
Run: `git status --short`
|
||||||
|
Expected: 仅包含后端实现文件与 `doc/implementation-report-2026-03-30-login-password-encryption-backend.md`
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add doc/implementation-report-2026-03-30-login-password-encryption-backend.md
|
||||||
|
git commit -m "完成密码加密传输后端实现"
|
||||||
|
```
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
# Frontend Password Transfer Encryption Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** 为正式密码提交接口补上前端加密发送能力,让登录、注册、个人修改密码、管理员重置密码、管理员新增用户在请求发出前只对密码字段做 AES 加密。
|
||||||
|
|
||||||
|
**Architecture:** 在 `ruoyi-ui` 新增统一的密码传输加密工具和字段映射辅助方法,由 API 层在提交请求前克隆并加密受控字段。页面组件继续持有明文表单值,现有表单校验和交互文案保持不变。
|
||||||
|
|
||||||
|
**Tech Stack:** Vue 2、Axios、`crypto-js`、Node 脚本测试、Vue CLI 4
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: 搭建前端加密工具与测试基线
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/package.json`
|
||||||
|
- Modify: `ruoyi-ui/package-lock.json`
|
||||||
|
- Create: `ruoyi-ui/src/utils/passwordTransfer.js`
|
||||||
|
- Create: `ruoyi-ui/tests/password-transfer-api.test.js`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 写前端失败测试脚本**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const encrypted = encryptPasswordFields(
|
||||||
|
{ password: 'admin123', code: '8888' },
|
||||||
|
['password'],
|
||||||
|
'1234567890abcdef'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.notStrictEqual(encrypted.password, 'admin123')
|
||||||
|
assert.strictEqual(encrypted.code, '8888')
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
const requestConfig = login('admin', 'admin123', '8888', 'uuid-1')
|
||||||
|
assert.strictEqual(requestConfig.data.password !== 'admin123', true)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认当前失败**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && node tests/password-transfer-api.test.js`
|
||||||
|
Expected: FAIL,工具文件或 API 加密行为尚不存在
|
||||||
|
|
||||||
|
- [ ] **Step 3: 新增依赖、脚本和最小工具实现**
|
||||||
|
|
||||||
|
```js
|
||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
|
||||||
|
export function encryptPasswordFields(payload, fields, key) {
|
||||||
|
const next = { ...payload }
|
||||||
|
fields.forEach((field) => {
|
||||||
|
if (next[field]) {
|
||||||
|
next[field] = CryptoJS.AES.encrypt(next[field], CryptoJS.enc.Utf8.parse(key), {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
}).toString()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return next
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
"scripts": {
|
||||||
|
"test:password-transfer": "node tests/password-transfer-api.test.js"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行前端测试**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/package.json ruoyi-ui/package-lock.json ruoyi-ui/src/utils/passwordTransfer.js ruoyi-ui/tests/password-transfer-api.test.js
|
||||||
|
git commit -m "新增前端密码加密工具"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 2: 接入登录与注册接口加密
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/api/login.js`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 扩展测试覆盖登录与注册 API**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const loginConfig = login('admin', 'admin123', '8888', 'uuid-1')
|
||||||
|
assert.notStrictEqual(loginConfig.data.password, 'admin123')
|
||||||
|
assert.strictEqual(loginConfig.data.username, 'admin')
|
||||||
|
|
||||||
|
const registerConfig = register({ username: 'u1', password: 'p1', confirmPassword: 'p1', code: '8888' })
|
||||||
|
assert.notStrictEqual(registerConfig.data.password, 'p1')
|
||||||
|
assert.strictEqual(registerConfig.data.confirmPassword, 'p1')
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认失败**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: FAIL,`login.js` 尚未对正式接口密码字段加密
|
||||||
|
|
||||||
|
- [ ] **Step 3: 在 API 层接入加密工具**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const data = encryptPasswordFields({ username, password, code, uuid }, ['password'], process.env.VUE_APP_PASSWORD_TRANSFER_KEY)
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
const payload = encryptPasswordFields(data, ['password'], process.env.VUE_APP_PASSWORD_TRANSFER_KEY)
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
- 只加密 `password`
|
||||||
|
- 保持字段名不变
|
||||||
|
- 不在页面组件中写加密逻辑
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行前端测试**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/api/login.js ruoyi-ui/tests/password-transfer-api.test.js
|
||||||
|
git commit -m "接入登录注册密码加密"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 3: 接入个人修改密码接口加密
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/api/system/user.js`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 扩展测试覆盖 `updateUserPwd`**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const config = updateUserPwd('oldPwd', 'newPwd')
|
||||||
|
assert.notStrictEqual(config.data.oldPassword, 'oldPwd')
|
||||||
|
assert.notStrictEqual(config.data.newPassword, 'newPwd')
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认失败**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: FAIL,`updateUserPwd` 仍发送明文
|
||||||
|
|
||||||
|
- [ ] **Step 3: 只在 API 层加密两个密码字段**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const data = encryptPasswordFields(
|
||||||
|
{ oldPassword, newPassword },
|
||||||
|
['oldPassword', 'newPassword'],
|
||||||
|
process.env.VUE_APP_PASSWORD_TRANSFER_KEY
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
- 页面 `resetPwd.vue` 不改
|
||||||
|
- 继续让前端表单在明文状态下完成确认密码校验
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行测试**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/api/system/user.js ruoyi-ui/tests/password-transfer-api.test.js
|
||||||
|
git commit -m "接入个人修改密码加密"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 4: 接入管理员新增用户与重置密码接口加密
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/api/system/user.js`
|
||||||
|
- Modify: `ruoyi-ui/.env.development`
|
||||||
|
- Modify: `ruoyi-ui/.env.staging`
|
||||||
|
- Modify: `ruoyi-ui/.env.production`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 扩展测试覆盖 `addUser` 与 `resetUserPwd`**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const addConfig = addUser({ userName: 'u1', password: 'initPwd', nickName: 'n1' })
|
||||||
|
assert.notStrictEqual(addConfig.data.password, 'initPwd')
|
||||||
|
|
||||||
|
const resetConfig = resetUserPwd(2, 'resetPwd')
|
||||||
|
assert.notStrictEqual(resetConfig.data.password, 'resetPwd')
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行测试确认失败**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: FAIL,`addUser`、`resetUserPwd` 仍发送明文
|
||||||
|
|
||||||
|
- [ ] **Step 3: 在受控接口接入加密并补环境配置**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const payload = encryptPasswordFields(data, ['password'], process.env.VUE_APP_PASSWORD_TRANSFER_KEY)
|
||||||
|
```
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
VUE_APP_PASSWORD_TRANSFER_KEY=请替换为16位固定密钥
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
- 只改 `addUser`、`resetUserPwd`
|
||||||
|
- `updateUser` 不做密码加密处理
|
||||||
|
- 三套环境文件都补同名配置项
|
||||||
|
|
||||||
|
- [ ] **Step 4: 重新运行测试**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add ruoyi-ui/src/api/system/user.js ruoyi-ui/.env.development ruoyi-ui/.env.staging ruoyi-ui/.env.production ruoyi-ui/tests/password-transfer-api.test.js
|
||||||
|
git commit -m "接入用户密码接口前端加密"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 5: 汇总验证与前端实施记录
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `doc/implementation-report-2026-03-30-login-password-encryption-frontend.md`
|
||||||
|
|
||||||
|
- [ ] **Step 1: 运行前端目标测试**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run test:password-transfer`
|
||||||
|
Expected: PASS,受控 API 的密码字段都按预期加密
|
||||||
|
|
||||||
|
- [ ] **Step 2: 运行一次前端构建验证**
|
||||||
|
|
||||||
|
Run: `cd ruoyi-ui && npm run build:stage`
|
||||||
|
Expected: PASS,新增依赖、环境变量与 API 修改不影响构建
|
||||||
|
|
||||||
|
- [ ] **Step 3: 写前端实施记录**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# 密码加密传输前端实施记录
|
||||||
|
- 新增强制密码字段加密工具
|
||||||
|
- 登录、注册、修改密码、重置密码、新增用户在 API 层加密
|
||||||
|
- 页面表单逻辑保持不变
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: 再次检查 git 状态**
|
||||||
|
|
||||||
|
Run: `git status --short`
|
||||||
|
Expected: 仅包含前端实现文件与 `doc/implementation-report-2026-03-30-login-password-encryption-frontend.md`
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交本任务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add doc/implementation-report-2026-03-30-login-password-encryption-frontend.md
|
||||||
|
git commit -m "完成密码加密传输前端实现"
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user