docs(change-password): 全面检查 - 5 issues
- §3.1 序列图弹窗描述过长 -> 简化为'5个UI区' - §4.3 GetByID 错误处理用 '...' 省略 -> 补完整(NotFound/wrap) - §4.5 错误映射表 - 删除重复的 ErrPasswordTooShort 行 - §10 文件变更总览 - 补 auth_service_login_test.go (§12.4 新增) - §11 部署清单 - 增 'API 接口回归' 和 '登录态回归' 重点 (401 不变,403 上升,500 下降)
This commit is contained in:
parent
397ebed805
commit
b15788d1fc
@ -53,7 +53,7 @@
|
||||
│ │ │ │ │
|
||||
│ 1.点击"修改密码" │ │ │ │
|
||||
├───────────────────────────→│ │ │ │
|
||||
│ │ 弹窗打开(展示5个UI区:手机号+验证码一行、短信码、3 个密码框) │ │ │
|
||||
│ │ 弹窗打开(5个UI区) │ │ │
|
||||
│ │ │ │ │
|
||||
│ 2.点"获取验证码" │ │ │ │
|
||||
├───────────────────────────→│ │ │ │
|
||||
@ -182,9 +182,14 @@ grep -rn "SaveVerifyToken\|GetVerifyToken\|DeleteVerifyToken\|VerifyToken(\|Save
|
||||
|
||||
```go
|
||||
func (s *userService) UpdatePassword(ctx context.Context, req *pb.UpdatePasswordRequest, userID int64) (*pb.UpdatePasswordResponse, error) {
|
||||
// 0. (新增) 验证短信 token
|
||||
// 0. (新增) 查询用户(后续需 user.Mobile 校验 verify_token)
|
||||
user, err := s.userRepo.GetByID(userID)
|
||||
if err != nil { ... }
|
||||
if err != nil {
|
||||
if errors.Is(err, appErrors.ErrUserNotFound) {
|
||||
return nil, appErrors.ErrUserNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get user: %w", err)
|
||||
}
|
||||
|
||||
if req.VerifyToken == "" {
|
||||
return nil, appErrors.ErrInvalidVerifyToken
|
||||
@ -313,17 +318,13 @@ func ToStatusCode(err error) pb.StatusCode {
|
||||
|
||||
**错误映射表(实施后)**:
|
||||
|
||||
| 错误 | 旧映射 | 新映射 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `ErrInvalidPassword`(Login 用) | 401 | 401 | 不变:登录场景下密码错 = 鉴权失败 |
|
||||
|
||||
| 错误 | 旧映射 | 新映射 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `ErrInvalidPassword`(Login 用) | 401 | 401 | 不变:登录场景下密码错 = 鉴权失败 |
|
||||
| `ErrInvalidOldPassword`(新,ChangePassword 用) | — | **400** | 改密场景下旧密码错 = 业务校验(用户已通过 AuthMiddleware 鉴权) |
|
||||
| `ErrPasswordTooShort` | 400 | 400 | 不变 |
|
||||
| `ErrInvalidVerifyToken`(新) | (旧方案 401) | **400** | 改密场景下短信 token 错 = 业务校验(用户已通过 AuthMiddleware 鉴权) |
|
||||
| `ErrSameAsOldPassword`(新) | 400 | 400 | 不变 |
|
||||
| `ErrPasswordTooShort` | 400 | 400 | 不变 |
|
||||
| `ErrUserInactive` | 500(实际落 default) | **403** | 修复:此前 ToStatusCode 没有 case 落到 default 500,本次显式映射 403;配合 §12 Login 流程一起修复 |
|
||||
| `ErrInvalidToken` / `ErrTokenExpired` / `ErrTokenMismatch` | 401 | 401 | 不变:真鉴权问题 |
|
||||
|
||||
@ -813,8 +814,9 @@ export function updatePasswordApi(oldPassword, newPassword, verifyToken) {
|
||||
| Service | 修改 | `backend/services/userService/service/sms_redis.go` |
|
||||
| Service | 修改 | `backend/services/userService/service/sms_service.go` |
|
||||
| Service | 修改 | `backend/services/userService/service/user_service.go` |
|
||||
| Service | 修改 | `backend/services/userService/service/auth_service.go`(Register 中 `VerifyToken(ctx, mobile, token)` → `VerifyToken(ctx, "register", mobile, token)`,共 1 处) |
|
||||
| Service | 新增 | `backend/services/userService/service/user_service_password_test.go` |
|
||||
| Service | 修改 | `backend/services/userService/service/auth_service.go`(Register 中 `VerifyToken(ctx, mobile, token)` → `VerifyToken(ctx, "register", mobile, token)`,共 1 处;§12 修复 Login 流程 2 处 `return` 改用 typed error) |
|
||||
| Service | 新增 | `backend/services/userService/service/user_service_password_test.go`(§4.6 10 个用例) |
|
||||
| Service | 新增 | `backend/services/userService/service/auth_service_login_test.go`(§12.4 2 个用例,banned/frozen 返 403) |
|
||||
| Provider | 修改 | `backend/services/userService/provider/user_provider.go`(传 ctx) |
|
||||
| Errors | 修改 | `backend/pkg/errors/errors.go`(新增 3 个错误码 `ErrInvalidVerifyToken`/`ErrSameAsOldPassword`/`ErrInvalidOldPassword`;`ToStatusCode` 中 `ErrInvalidVerifyToken` 改映射 400;`ToStatusCode` 改用 `errors.Is` 全面识别 wrapped error;新增 `NewAccountBannedError` / `NewAccountFrozenError` 2 个 helper) |
|
||||
| Frontend utils | 修改 | `frontend/utils/api.js`(拦截器去掉 400 自动登出,保留 401/403 + `updatePasswordApi` 增 `verify_token` 字段) |
|
||||
@ -826,10 +828,15 @@ export function updatePasswordApi(oldPassword, newPassword, verifyToken) {
|
||||
|
||||
- [ ] proto 重新生成后,所有引用 `UpdatePasswordRequest` 的代码编译通过
|
||||
- [ ] Redis key 升级:老的 `sms:register:*` / `verify:register:*` 数据保留(Register 仍用 scene=register);新加的 `sms:password:*` / `verify:password:*` 独立
|
||||
- [ ] 后端单测全绿
|
||||
- [ ] **API 接口回归**: Login / Register / RefreshToken / Logout / GetMyProfile / UpdateNickname 等所有走 `ToStatusCode` 的接口,在 `errors.Is` 改造后行为不变(单测 + 灰度验证)
|
||||
- [ ] **登录态回归**: 在修复 BUG #1(拦截器去掉 400 自动登出)后,跑一遍以下场景确认无回归:
|
||||
- 输错密码登录(Login 接口返 401)→ 前端拦截器跳登录 ✅
|
||||
- 账号被冻结登录(§12 修复后应返 403,而非 500)→ 弹封禁原因 + 跳登录 ✅
|
||||
- 业务校验错(改密输错旧密码,本次返 400)→ toast 提示,不跳登录 ✅
|
||||
- [ ] 后端单测全绿(含 §4.6 10 个 + §12.4 2 个)
|
||||
- [ ] 前端手动验证 10 条 checklist 通过
|
||||
- [ ] Swagger 文档重新生成
|
||||
- [ ] 灰度发布,先开 10% 流量观察错误率
|
||||
- [ ] 灰度发布,先开 10% 流量观察错误率,重点监控 401/403/500 比例(应:401 不变,403 上升,500 下降)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user