664 lines
18 KiB
Markdown
664 lines
18 KiB
Markdown
# PRD 与实现差异报告
|
||
|
||
**文档版本**: v3.0
|
||
**生成日期**: 2026-03-29
|
||
**审查范围**: PRD.md vs 实际代码实现
|
||
**审查方法**: 代码级验证(Agent 辅助分析)
|
||
|
||
---
|
||
|
||
## 一、已实现功能 ✓
|
||
|
||
### 1.1 用户注册与登录
|
||
|
||
| PRD 功能 | 实现状态 | 代码证据 |
|
||
|----------|----------|----------|
|
||
| 邮箱注册 + 激活验证 | ✓ | `auth.go` Register(), ActivateEmail |
|
||
| 手机号注册 | ✓ | `sms.go` SendCode, LoginByCode |
|
||
| 用户名注册 | ✓ | `auth.go` Register() |
|
||
| 密码登录 | ✓ | `auth.go` Login() |
|
||
| 验证码登录(邮箱) | ✓ | `auth_email.go` LoginByEmailCode() |
|
||
| 验证码登录(手机) | ✓ | `sms.go` LoginByCode() |
|
||
| 社交账号登录 | ✓ | `auth.go` OAuthLogin/OAuthCallback |
|
||
| TOTP 双因素认证 | ✓ | `totp.go` Setup/Enable/Disable/Verify |
|
||
| 密码强度验证 | ✓ | `auth.go` GetPasswordStrength() |
|
||
| 密码重置(邮箱) | ✓ | `password_reset.go` |
|
||
| 头像上传 | ✓ | `avatar.go` |
|
||
| 图形验证码 | ✓ | `captcha.go` |
|
||
|
||
### 1.2 社交登录集成
|
||
|
||
| 平台 | 实现状态 |
|
||
|------|----------|
|
||
| 微信 (WeChat) | ✓ |
|
||
| QQ | ✓ |
|
||
| 支付宝 (Alipay) | ✓ |
|
||
| 抖音 (Douyin) | ✓ |
|
||
| GitHub | ✓ |
|
||
| Google | ✓ |
|
||
| Facebook | ✓ |
|
||
| Twitter | ✓ |
|
||
| 微博 (Weibo) | ✓ |
|
||
|
||
### 1.3 授权与认证
|
||
|
||
| 功能 | 实现状态 | 代码证据 |
|
||
|------|----------|----------|
|
||
| JWT Access Token (RS256) | ✓ | `jwt.go` RS256 支持 |
|
||
| Refresh Token | ✓ | `auth.go` RefreshToken() |
|
||
| Token 黑名单 | ✓ | `auth.go` blacklistTokenClaims() |
|
||
| CSRF Token | ✓ | `csrf.go` |
|
||
| OAuth 2.0 | ✓ | `auth.go` OAuth* |
|
||
| 登录失败锁定 | ✓ | `auth.go` recordLoginAnomaly() |
|
||
|
||
### 1.4 权限管理 (RBAC)
|
||
|
||
| 功能 | 实现状态 | 代码证据 |
|
||
|------|----------|----------|
|
||
| 用户-角色-权限模型 | ✓ | `role_permission.go` |
|
||
| 角色 CRUD | ✓ | `role.go` |
|
||
| 权限 CRUD | ✓ | `permission.go` |
|
||
| 角色分配 | ✓ | `user.go` AssignRoles() |
|
||
| 权限校验中间件 | ✓ | `auth.go` RequirePermission() |
|
||
| 默认角色 | ✓ | `domain/role.go` PredefinedRoles |
|
||
| 角色继承数据结构 | ✓ | Role.ParentID, Role.Level 字段存在 |
|
||
|
||
### 1.5 用户管理
|
||
|
||
| 功能 | 实现状态 | 代码证据 |
|
||
|------|----------|----------|
|
||
| 用户列表(分页/筛选/排序) | ✓ | `user.go` ListUsers() |
|
||
| 创建/编辑/删除用户 | ✓ | `user.go` |
|
||
| 用户状态管理 | ✓ | `user.go` UpdateUserStatus() |
|
||
| 登录日志 | ✓ | `login_log.go` |
|
||
| 操作日志 | ✓ | `operation_log.go` middleware |
|
||
| 用户导入/导出 | ✓ | `export.go` |
|
||
| 密码历史记录 | ✓ | `user.go` 实际使用 |
|
||
|
||
### 1.6 系统集成
|
||
|
||
| 功能 | 实现状态 | 代码证据 |
|
||
|------|----------|----------|
|
||
| RESTful API | ✓ | Gin router |
|
||
| Swagger/OpenAPI | ✓ | `swagger/*` |
|
||
| Webhook 事件通知 | ✓ | `webhook.go` 完整实现 |
|
||
| Admin 管理后台 | ✓ | React frontend |
|
||
| 健康检查端点 | ✓ | `/health`, `/health/live`, `/health/ready` |
|
||
| Prometheus 指标 | ✓ | `/metrics` |
|
||
|
||
### 1.7 安全机制
|
||
|
||
| 功能 | 实现状态 | 代码证据 |
|
||
|------|----------|----------|
|
||
| 登录失败锁定 | ✓ | `auth.go` |
|
||
| 图形验证码 | ✓ | `captcha.go` |
|
||
| IP 白名单/黑名单 | ✓ | `ip_filter.go` |
|
||
| 接口限流 | ✓ | `ratelimit.go` |
|
||
| 敏感操作 2FA | ✓ | TOTP 校验 |
|
||
| Argon2id 密码加密 | ✓ | `auth.go` HashPassword |
|
||
|
||
---
|
||
|
||
## 二、未实现功能
|
||
|
||
### 2.1 角色继承逻辑 ⚠️ 部分实现
|
||
|
||
**PRD 描述**: 子角色自动继承父角色权限
|
||
|
||
**实际情况**:
|
||
- `Role` 结构有 `ParentID` 和 `Level` 字段 ✓
|
||
- `GetRolePermissions()` **只获取直接分配的权限** ✗
|
||
- 没有递归遍历父角色收集权限的逻辑
|
||
|
||
**证据** (`role_permission.go`):
|
||
```go
|
||
// GetPermissionIDsByRoleIDs 只获取直接关联的权限
|
||
err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).
|
||
Where("role_id IN ?", roleIDs).
|
||
Pluck("permission_id", &permissionIDs).Error
|
||
```
|
||
|
||
**影响**: 父子角色权限继承不生效
|
||
|
||
---
|
||
|
||
### 2.2 密码重置(手机短信)
|
||
|
||
**PRD 描述**: 手机验证码重置密码
|
||
|
||
**实际情况**: 未实现
|
||
- 只有邮箱重置 `password_reset.go`
|
||
- 没有短信验证码重置密码的 API
|
||
|
||
---
|
||
|
||
### 2.3 设备信任功能
|
||
|
||
**PRD 描述**:
|
||
- "记住此设备" 免二次验证
|
||
- 信任期限可配置(7-30 天)
|
||
- 一键下线所有其他设备
|
||
|
||
**实际情况**: 部分实现
|
||
- 设备管理 CRUD 已实现 ✓
|
||
- "记住设备" 功能未实现 ✗
|
||
- 信任期限配置未实现 ✗
|
||
- 一键下线其他设备未实现 ✗
|
||
|
||
---
|
||
|
||
### 2.4 自定义字段扩展
|
||
|
||
**PRD 描述**: 用户自定义字段,JSON 格式存储,字段类型验证
|
||
|
||
**实际情况**: 未实现
|
||
- `User` 结构没有 `custom_fields` 字段
|
||
- 没有字段验证规则配置
|
||
|
||
---
|
||
|
||
### 2.5 自定义主题配置
|
||
|
||
**PRD 描述**: 自定义登录页面样式、Logo 替换、主题色
|
||
|
||
**实际情况**: 未实现
|
||
- 登录页面使用固定样式
|
||
|
||
---
|
||
|
||
### 2.6 SSO 单点登录
|
||
|
||
**PRD 描述**: CAS、SAML 协议支持
|
||
|
||
**实际情况**: 未实现
|
||
- 没有 CAS/SAML 相关代码
|
||
|
||
---
|
||
|
||
### 2.7 异地登录检测
|
||
|
||
**PRD 描述**: 记录常用地区,异地登录通知
|
||
|
||
**实际情况**: 未实现
|
||
- `login_logs` 表有 `location` 字段但未用于异常检测
|
||
|
||
---
|
||
|
||
### 2.8 异常设备检测
|
||
|
||
**PRD 描述**: 设备指纹识别,新设备验证,异常告警
|
||
|
||
**实际情况**: 未实现
|
||
- 有设备信息记录但无指纹识别
|
||
|
||
---
|
||
|
||
### 2.9 "记住登录状态" 功能
|
||
|
||
**PRD 描述**: 密码登录时可选 "记住我"
|
||
|
||
**实际情况**: 未实现
|
||
- Refresh Token 机制存在但前端无此选项
|
||
|
||
---
|
||
|
||
## 三、功能完成度统计
|
||
|
||
| 模块 | PRD 需求数 | 已实现数 | 完成率 |
|
||
|------|-----------|----------|--------|
|
||
| 用户注册与登录 | 12 | 11 | 92% |
|
||
| 社交登录集成 | 6 | 6 | 100% |
|
||
| 授权与认证 | 6 | 6 | 100% |
|
||
| 权限管理 | 7 | 6 | 86% |
|
||
| 用户管理 | 10 | 9 | 90% |
|
||
| 系统集成 | 6 | 6 | 100% |
|
||
| 安全与风控 | 10 | 9 | 90% |
|
||
| 监控与运维 | 4 | 4 | 100% |
|
||
| **总计** | **61** | **57** | **93%** |
|
||
|
||
---
|
||
|
||
## 四、建议修复优先级
|
||
|
||
| 优先级 | 功能 | 原因 | 工作量 |
|
||
|--------|------|------|--------|
|
||
| 高 | 角色继承逻辑 | 数据结构已有,需补全查询逻辑 | 中 |
|
||
| 中 | 设备信任功能 | 安全增强 | 中 |
|
||
| 中 | 短信密码重置 | 用户体验 | 低 |
|
||
| 低 | 自定义字段 | 需要schema设计 | 高 |
|
||
| 低 | 自定义主题 | 边缘需求 | 中 |
|
||
| 低 | SSO | 复杂协议 | 高 |
|
||
|
||
---
|
||
|
||
## 五、代码质量问题(通过专业代码审查发现)
|
||
|
||
### 5.1 性能问题
|
||
|
||
#### 5.1.1 N+1 查询问题 ⚠️
|
||
|
||
**位置**: `internal/api/middleware/auth.go:131-177`
|
||
|
||
**问题描述**: `loadUserRolesAndPerms` 方法每次认证请求触发 4 次数据库查询:
|
||
|
||
1. `GetRoleIDsByUserID` - 查询用户角色
|
||
2. `GetByIDs` - 查询角色详情
|
||
3. `GetPermissionIDsByRoleIDs` - 查询角色权限
|
||
4. `GetByIDs` - 查询权限详情
|
||
|
||
**证据**:
|
||
```go
|
||
func (m *AuthMiddleware) loadUserRolesAndPerms(ctx context.Context, userID int64) ([]string, []string) {
|
||
roleIDs, err := m.userRoleRepo.GetRoleIDsByUserID(ctx, userID) // 查询1
|
||
// ...
|
||
roles, err := m.roleRepo.GetByIDs(ctx, roleIDs) // 查询2 (批量)
|
||
// ...
|
||
permIDs, err := m.rolePermRepo.GetPermissionIDsByRoleIDs(ctx, roleIDs) // 查询3
|
||
// ...
|
||
perms, err := m.permRepo.GetByIDs(ctx, permIDs) // 查询4 (批量)
|
||
}
|
||
```
|
||
|
||
**建议**: 将这 4 个查询合并为 1 个 JOIN 查询,或增加 L1 缓存 TTL(如 15-30 分钟)。
|
||
|
||
---
|
||
|
||
**补充位置**: `internal/service/role.go:194-212` 也有类似问题,`GetRolePermissions` 方法在循环中单独查询每个权限。
|
||
|
||
---
|
||
|
||
#### 5.1.2 正则表达式重复编译 ⚠️
|
||
|
||
**位置**: `internal/security/validator.go:98-101`, `129-136`
|
||
|
||
**问题描述**: `SanitizeSQL` 和 `SanitizeXSS` 在每次调用时都在循环内使用 `regexp.MustCompile`,导致正则表达式重复编译,影响性能。
|
||
|
||
**证据**:
|
||
```go
|
||
for _, pattern := range dangerousPatterns {
|
||
re := regexp.MustCompile(`(?i)` + pattern) // 每次调用都重新编译
|
||
result = re.ReplaceAllString(result, "")
|
||
}
|
||
```
|
||
|
||
**建议**: 预编译正则表达式并复用,或使用 `regexp.Regexp` 实例。
|
||
|
||
---
|
||
|
||
#### 5.1.3 设备列表查询无分页限制 ⚠️
|
||
|
||
**位置**: `internal/service/device.go:142-152`
|
||
|
||
**问题描述**: `GetUserDevices` 方法虽然有 `page` 和 `pageSize` 参数,但如果传入负数或零值,可能导致全表扫描。
|
||
|
||
**建议**: 在 service 层增加参数校验,确保分页参数有效。
|
||
|
||
---
|
||
|
||
### 5.2 安全问题
|
||
|
||
#### 5.2.1 敏感操作验证绕过风险 ⚠️
|
||
|
||
**位置**: `internal/service/auth.go:1068-1102`
|
||
|
||
**问题描述**: `verifySensitiveAction` 方法在密码和 TOTP 都为空时直接返回成功,可能导致敏感操作(如解绑社交账号)无需验证。
|
||
|
||
**证据**:
|
||
```go
|
||
if password != "" {
|
||
// 验证密码
|
||
}
|
||
if code != "" {
|
||
// 验证TOTP
|
||
}
|
||
// 如果都没有,且用户有密码或TOTP,仍然返回nil
|
||
if hasPassword || hasTOTP {
|
||
return errors.New("password or TOTP verification is required")
|
||
}
|
||
return nil // 当用户没有密码也没有TOTP时,这里直接返回nil
|
||
```
|
||
|
||
**影响**: 如果用户没有设置密码也没有启用TOTP,可以无需任何验证即可解绑社交账号。
|
||
|
||
---
|
||
|
||
#### 5.2.2 设备字段长度未校验 ⚠️
|
||
|
||
**位置**: `internal/service/device.go:52-92`
|
||
|
||
**问题描述**: `CreateDeviceRequest` 中 `DeviceID`、`DeviceName` 等字段没有长度校验,可能导致数据库存储问题。
|
||
|
||
**证据**:
|
||
```go
|
||
type CreateDeviceRequest struct {
|
||
DeviceID string `json:"device_id" binding:"required"`
|
||
DeviceName string `json:"device_name"`
|
||
// 缺少 binding:"max=100" 等校验
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 5.2.3 登录日志异步写入失败无告警 ⚠️
|
||
|
||
**位置**: `internal/service/auth.go:470-474`
|
||
|
||
**问题描述**: `writeLoginLog` 方法使用 goroutine 异步写入日志,但失败时只是打印日志,没有告警机制。
|
||
|
||
**证据**:
|
||
```go
|
||
go func() {
|
||
if err := s.loginLogRepo.Create(context.Background(), loginRecord); err != nil {
|
||
log.Printf("auth: write login log failed...") // 仅打印日志
|
||
}
|
||
}()
|
||
```
|
||
|
||
**建议**: 对于安全相关日志,应考虑使用专门的安全日志系统或至少记录指标。
|
||
|
||
---
|
||
|
||
### 5.3 代码质量问题
|
||
|
||
#### 5.3.1 重复的用户名生成逻辑 ⚠️
|
||
|
||
**位置**: `internal/service/auth.go:243-274`
|
||
|
||
**问题描述**: `generateUniqueUsername` 中使用循环查询数据库检查用户名是否存在,每次循环都是一次数据库查询。最多可能执行 1000 次查询。
|
||
|
||
**证据**:
|
||
```go
|
||
for i := 1; i <= 1000; i++ {
|
||
candidate := fmt.Sprintf("%s_%d", username, i)
|
||
exists, err = s.userRepo.ExistsByUsername(ctx, candidate)
|
||
// 每次循环都有一次数据库查询
|
||
}
|
||
```
|
||
|
||
**建议**: 使用数据库唯一索引 + 错误重试机制替代循环查询。
|
||
|
||
---
|
||
|
||
#### 5.3.2 字符串处理重复 ⚠️
|
||
|
||
**位置**: 多处
|
||
|
||
**问题描述**: 代码中多次出现类似的字符串处理逻辑:
|
||
- `strings.TrimSpace` + `strings.ToLower` 组合
|
||
- 重复的正则表达式模式
|
||
|
||
**示例**:
|
||
```go
|
||
// auth.go 多次使用
|
||
strings.ToLower(strings.TrimSpace(provider))
|
||
strings.TrimSpace(oauthUser.Email)
|
||
```
|
||
|
||
**建议**: 提取公共工具函数复用。
|
||
|
||
---
|
||
|
||
#### 5.3.3 错误处理不一致 ⚠️
|
||
|
||
**位置**: `internal/service/auth.go` 多处
|
||
|
||
**问题描述**: 部分函数在错误时返回具体错误消息,部分返回通用错误,API 响应不一致。
|
||
|
||
**示例**:
|
||
```go
|
||
// 有些返回具体错误
|
||
return nil, errors.New("账号已锁定,请稍后再试")
|
||
|
||
// 有些返回通用错误
|
||
return nil, errors.New("auth service is not fully configured")
|
||
```
|
||
|
||
**建议**: 统一错误处理模式,使用错误码或自定义错误类型。
|
||
|
||
---
|
||
|
||
#### 5.3.4 硬编码魔法数字 ⚠️
|
||
|
||
**位置**: 多处
|
||
|
||
**问题描述**: 代码中存在未定义常量的魔法数字。
|
||
|
||
**示例**:
|
||
```go
|
||
// auth.go:262
|
||
for i := 1; i <= 1000; i++ { // 1000 是什么?
|
||
|
||
// role.go:72-73
|
||
if req.ParentID != nil {
|
||
role.Level = 2 // Level = 2 是什么意思?
|
||
}
|
||
```
|
||
|
||
**建议**: 使用有名称的常量替代魔法数字。
|
||
|
||
---
|
||
|
||
### 5.4 代码审查总结
|
||
|
||
| 问题类型 | 数量 | 严重程度 |
|
||
|---------|------|----------|
|
||
| 性能问题 | 3 | 中 |
|
||
| 安全问题 | 3 | 中-高 |
|
||
| 代码质量问题 | 4 | 低-中 |
|
||
|
||
**关键问题**:
|
||
1. **必须修复**: 敏感操作验证绕过风险 (5.2.1)
|
||
2. **应该修复**: N+1 查询问题 (5.1.1)、正则表达式重复编译 (5.1.2)
|
||
3. **建议修复**: 用户名生成逻辑 (5.3.1)、错误处理不一致 (5.3.3)
|
||
|
||
---
|
||
|
||
## 六、新发现的安全漏洞(Agent 详细审查)
|
||
|
||
### 6.1 高危安全问题
|
||
|
||
#### [SEC-01] OAuth ValidateToken 方法形同虚设 ⚠️⚠️
|
||
|
||
**文件**: `internal/auth/oauth.go:436-446`
|
||
|
||
**问题描述**: `ValidateToken` 方法始终返回 `true`,完全没有验证 token 的有效性。
|
||
|
||
**证据**:
|
||
```go
|
||
func (m *DefaultOAuthManager) ValidateToken(token string) (bool, error) {
|
||
if len(token) == 0 {
|
||
return false, nil
|
||
}
|
||
return true, nil // <-- 始终返回 true
|
||
}
|
||
```
|
||
|
||
**影响**: 调用方以为做了验证,实际什么都没做。
|
||
|
||
---
|
||
|
||
#### [SEC-02] 敏感操作验证绕过 ⚠️⚠️
|
||
|
||
**文件**: `internal/service/auth.go:1068-1102`
|
||
|
||
**问题描述**: 当用户没有设置密码也没有启用 TOTP 时,`verifySensitiveAction` 直接返回成功。
|
||
|
||
**证据**:
|
||
```go
|
||
if hasPassword || hasTOTP {
|
||
return errors.New("password or TOTP verification is required")
|
||
}
|
||
return nil // <-- 无密码无TOTP时直接通过
|
||
```
|
||
|
||
**影响**: 可以无需任何验证即可解绑社交账号。
|
||
|
||
---
|
||
|
||
#### [SEC-03] 恢复码明文存储 ⚠️⚠️
|
||
|
||
**文件**: `internal/service/auth.go:1117-1132`
|
||
|
||
**问题描述**: TOTP 恢复码以明文 JSON 存储在数据库中。
|
||
|
||
**修复建议**: 使用 bcrypt/Argon2 对恢复码进行哈希后存储。
|
||
|
||
---
|
||
|
||
#### [SEC-04] TOTP 算法使用 SHA1(已知弱点)⚠️
|
||
|
||
**文件**: `internal/auth/totp.go:25`
|
||
|
||
**问题描述**: 代码使用 SHA1 作为 TOTP 算法,Google Authenticator 等已迁移到 SHA256。
|
||
|
||
---
|
||
|
||
#### [SEC-05] X-Forwarded-For IP 伪造风险 ⚠️
|
||
|
||
**文件**: `internal/api/middleware/ip_filter.go:50-65`
|
||
|
||
**问题描述**: 中间件直接信任 `X-Forwarded-For` 请求头,攻击者可伪造任意 IP 绕过黑名单。
|
||
|
||
---
|
||
|
||
#### [SEC-06] JTI 包含可预测的时间戳 ⚠️
|
||
|
||
**文件**: `internal/auth/jwt.go:58-66`
|
||
|
||
**问题描述**: JTI 格式为 `fmt.Sprintf("%x-%d", b, time.Now().UnixNano())`,追加了可预测的时间戳。
|
||
|
||
---
|
||
|
||
#### [SEC-07] OAuth State 验证存在 TOCTOU 竞态条件 ⚠️
|
||
|
||
**文件**: `internal/auth/oauth_utils.go:42-64`
|
||
|
||
**问题描述**: 过期检查和删除操作不在同一个锁区域内,存在竞态条件。
|
||
|
||
---
|
||
|
||
#### [SEC-08] 刷新令牌接口缺少速率限制 ⚠️
|
||
|
||
**文件**: `internal/api/router/router.go:108`
|
||
|
||
**问题描述**: `/auth/refresh` 接口没有限流中间件。
|
||
|
||
---
|
||
|
||
### 6.2 中危安全问题
|
||
|
||
| ID | 问题 | 文件位置 |
|
||
|----|------|----------|
|
||
| SEC-09 | CSRF Token 接口无 CSRF 保护 | auth.go:673-683 |
|
||
| SEC-10 | Session Presence Cookie 不是 HttpOnly | auth.go:117 |
|
||
| SEC-11 | rand.Read 错误被忽略 | oauth_utils.go:30 |
|
||
| SEC-12 | 日志泄露敏感信息 | 多处 |
|
||
| SEC-14 | 默认 Argon2 参数偏弱 (iterations=3) | password.go:29 |
|
||
| SEC-15 | 登录失败时泄露用户存在性 | auth.go:649-652 |
|
||
| SEC-16 | Cache 失效时锁定机制失效 | auth.go:640-647 |
|
||
|
||
---
|
||
|
||
## 七、新发现的性能问题(Agent 详细审查)
|
||
|
||
### 7.1 N+1 查询问题
|
||
|
||
#### [PERF-01] 每次认证请求触发 4 次数据库查询
|
||
|
||
**文件**: `internal/api/middleware/auth.go:131-177`
|
||
|
||
每个认证请求依次执行:
|
||
1. `GetRoleIDsByUserID` - 查询用户角色
|
||
2. `GetByIDs` - 查询角色详情
|
||
3. `GetPermissionIDsByRoleIDs` - 查询角色权限
|
||
4. `GetByIDs` - 查询权限详情
|
||
|
||
---
|
||
|
||
#### [PERF-03] findUserForLogin 串行查询 3 次数据库
|
||
|
||
**文件**: `internal/service/auth_runtime.go:32-54`
|
||
|
||
按 username -> email -> phone 顺序串行查询,最坏情况需 3 次数据库往返。
|
||
|
||
---
|
||
|
||
### 7.2 其他性能问题
|
||
|
||
| ID | 问题 | 文件位置 |
|
||
|----|------|----------|
|
||
| PERF-02 | OAuth State 存储无自动清理 | oauth_utils.go:23 |
|
||
| PERF-04 | 限流器清理策略不完善 | ratelimit.go:175 |
|
||
| PERF-05 | 重复缓存用户信息 | auth.go:686,1195 |
|
||
| PERF-06 | CacheManager 同步双写 L1+L2 | cache_manager.go:42 |
|
||
| PERF-07 | goroutine 无超时地写数据库 | auth.go:470 |
|
||
| PERF-08 | L1Cache 无自动清理 | l1.go |
|
||
| PERF-09 | AnomalyDetector records 无上限 | ip_filter.go:258 |
|
||
|
||
---
|
||
|
||
## 八、代码重复问题(Agent 详细审查)
|
||
|
||
### 8.1 严重重复
|
||
|
||
| 问题 | 文件 | 说明 |
|
||
|------|------|------|
|
||
| OAuth State 管理器重复 | `state.go` vs `oauth_utils.go` | 两套完全独立的实现 |
|
||
| Handler 授权函数重复 | `authz.go` vs `user.go` | 5个函数完全相同 |
|
||
| 分页逻辑重复 | 多个 service/handler | 每个文件都有相同的分页代码 |
|
||
| 密码强度验证重复 | `password_policy.go` vs `auth.go` | 相同逻辑重复实现 |
|
||
| 验证码生成重复 | `email.go` vs `sms.go` vs `captcha.go` | 三种不同实现 |
|
||
|
||
### 8.2 建议重构优先级
|
||
|
||
1. **立即修复**: OAuth State 重复、Handler 授权函数重复
|
||
2. **短期修复**: 分页逻辑统一、LIKE 查询转义
|
||
3. **中期优化**: 验证码生成统一、密码策略统一
|
||
|
||
---
|
||
|
||
## 九、代码质量审查总结
|
||
|
||
### 问题统计
|
||
|
||
| 类别 | 数量 | 严重程度 |
|
||
|------|------|----------|
|
||
| 高危安全问题 | 8 | 高 |
|
||
| 中危安全问题 | 7 | 中 |
|
||
| 性能问题 | 12 | 中-低 |
|
||
| 代码重复 | 20+ | 中 |
|
||
| 代码质量问题 | 37+ | 低-中 |
|
||
|
||
### 关键修复清单
|
||
|
||
**必须立即修复**:
|
||
1. [SEC-01] OAuth ValidateToken 始终返回 true
|
||
2. [SEC-02] 敏感操作验证绕过漏洞
|
||
3. [SEC-03] 恢复码明文存储
|
||
4. [SEC-05] IP 伪造风险
|
||
|
||
**应该修复**:
|
||
1. [PERF-01-03] N+1 查询和串行查询问题
|
||
2. [PERF-07] goroutine 无超时问题
|
||
3. 代码重复问题(state.go, authz.go 等)
|
||
|
||
**建议修复**:
|
||
1. [SEC-14] Argon2 iterations 参数偏低
|
||
2. [PERF-04-09] 其他性能和资源管理问题
|
||
3. 错误处理不一致、魔法字符串等问题
|
||
|
||
本报告通过以下方式验证:
|
||
1. 代码级分析(Agent 工具遍历所有相关文件)
|
||
2. API endpoint 对比 router.go
|
||
3. 数据模型检查 domain/*.go
|
||
4. 业务逻辑检查 service/*.go
|
||
5. 代码质量审查(使用 Simplify Skill 进行专业化审查)
|
||
- 代码重复和可复用性分析
|
||
- 安全漏洞和性能问题分析
|
||
- 代码质量和设计模式审查
|
||
|
||
---
|
||
|
||
*本报告由系统审查生成,审查日期:2026-03-29*
|
||
*版本历史: v1.0 初始版本, v2.0 功能差异分析, v3.0 增加代码质量审查, v3.1 增加详细安全/性能审查*
|