Files
huang 9c399df6bc feat(auth): 新增系统启动时自动初始化默认超级管理员功能
- 新增默认管理员自动初始化逻辑,系统启动时检查并创建超级管理员账号
- 支持通过配置文件自定义账号信息(优先级:配置文件 > 代码默认值)
- 新增 CreateSystemAccount 方法用于系统内部账号创建
- 新增默认管理员配置项和常量定义
- 更新 README.md 添加默认账号使用说明
- 归档 OpenSpec 变更提案及完整文档

相关文件:
- internal/bootstrap/admin.go: 管理员初始化逻辑
- internal/service/account/service.go: 系统账号创建方法
- pkg/config/config.go: 默认管理员配置结构
- pkg/constants/constants.go: 默认值常量定义
- docs/add-default-admin-init/功能说明.md: 完整功能文档
2026-01-14 10:53:42 +08:00

8.1 KiB
Raw Permalink Blame History

auth Specification

Purpose

TBD - created by archiving change refactor-framework-cleanup. Update Purpose after archive.

Requirements

Requirement: Unified Authentication Middleware

系统 SHALL 提供统一的认证中间件,支持可配置的 Token 提取和验证。

Scenario: Token 验证成功

  • WHEN 请求携带有效的 Token
  • THEN 中间件提取并验证 Token
  • AND 将用户信息同时设置到 Fiber Locals 和 Context
  • AND 请求继续执行

Scenario: Token 缺失

  • WHEN 请求未携带 Token
  • AND 路径不在跳过列表中
  • THEN 返回 AppErrorCodeMissingToken
  • AND 由全局 ErrorHandler 处理错误响应

Scenario: Token 无效

  • WHEN 请求携带的 Token 无效或过期
  • THEN 返回 AppErrorCodeUnauthorized
  • AND 由全局 ErrorHandler 处理错误响应

Scenario: 跳过路径

  • WHEN 请求路径在 SkipPaths 配置中
  • THEN 中间件跳过认证
  • AND 请求直接继续执行

Requirement: User Context Management

认证中间件 SHALL 提供用户上下文管理函数,支持从 Context 获取用户信息。

Scenario: 获取用户 ID

  • WHEN 调用 GetUserIDFromContext(ctx)
  • AND 认证已通过
  • THEN 返回当前用户的 ID

Scenario: 检查 Root 用户

  • WHEN 调用 IsRootUser(ctx)
  • THEN 返回当前用户是否为 Root 用户

Scenario: 设置用户到 Fiber Context

  • WHEN 调用 SetUserToFiberContext(c, userInfo)
  • THEN 用户信息被设置到 Fiber Locals
  • AND 用户信息被设置到请求 Context供 GORM 等使用)

Requirement: Auth Middleware Configuration

认证中间件 SHALL 支持灵活的配置选项。

Scenario: 自定义 Token 提取

  • WHEN 配置了 TokenExtractor 函数
  • THEN 使用自定义函数从请求中提取 Token

Scenario: 默认 Token 提取

  • WHEN 未配置 TokenExtractor
  • THEN 从 Authorization Header 提取 Bearer Token

Scenario: 自定义验证函数

  • WHEN 配置了 Validator 函数
  • THEN 使用自定义函数验证 Token 并返回用户信息

Requirement: 启动时自动初始化默认管理员

系统在 API 服务启动时 SHALL 检查数据库是否存在超级管理员账号,如果不存在则自动创建默认管理员账号。

业务规则

  • 检查条件:user_type = 1(超级管理员)且未被软删除的账号
  • 仅在不存在时创建,存在管理员时跳过
  • 默认账号信息读取优先级:
    1. 配置文件优先:读取 config.yamldefault_admin 配置节
    2. 代码默认值:如果配置文件未提供,使用代码内置常量
  • 代码内置默认值:
    • 用户名:admin
    • 密码:Admin@123456bcrypt 哈希存储)
    • 手机号:13800000000
    • 用户类型:1(超级管理员)
    • 状态:1(启用)
  • 初始化失败不中断服务启动(记录错误日志,降级处理)

Scenario: 空数据库首次启动(使用代码默认值)

  • WHEN API 服务启动且数据库中不存在任何超级管理员账号
  • AND 配置文件未提供 default_admin 配置
  • THEN 系统使用代码内置默认值创建管理员账号
  • AND 用户名为 admin,密码为 Admin@123456,手机号为 13800000000
  • AND 记录日志:"已创建默认管理员账号: admin使用代码默认值"
  • AND 创建的账号可以正常使用(密码验证通过)

Scenario: 空数据库首次启动(使用配置文件)

  • WHEN API 服务启动且数据库中不存在任何超级管理员账号
  • AND 配置文件提供了 default_admin 配置
  • THEN 系统使用配置文件中的值创建管理员账号
  • AND 用户名、密码、手机号均从配置文件读取
  • AND 记录日志:"已创建默认管理员账号: {username}(使用配置文件)"
  • AND 创建的账号可以正常使用(配置的密码验证通过)

Scenario: 已有管理员时启动

  • WHEN API 服务启动且数据库中已存在至少一个超级管理员账号
  • THEN 系统跳过创建默认管理员
  • AND 记录日志:"检测到已有管理员账号,跳过初始化"
  • AND 不创建任何新账号

Scenario: 用户名或手机号冲突

  • WHEN API 服务启动且尝试创建默认管理员
  • AND 数据库中已存在用户名为 admin 或手机号为 13800000000 的账号(非超级管理员)
  • THEN 系统创建失败
  • AND 记录错误日志:"创建默认管理员失败: 用户名或手机号已存在"
  • AND 不中断服务启动(降级处理)

Scenario: 初始化执行时机

  • WHEN API 服务执行启动流程
  • THEN 管理员初始化在以下时机执行:
    1. 所有组件Store、Service、Handler初始化完成后
    2. 注册路由前
    3. 服务器开始监听前
  • AND 确保 AccountStore 可用时才执行初始化

Requirement: 默认管理员配置支持

系统 SHALL 支持通过配置文件自定义默认管理员账号信息,配置文件优先级高于代码默认值。

配置格式

default_admin:
  username: "admin"         # 可选,默认 "admin"
  password: "Admin@123456"  # 可选,默认 "Admin@123456"
  phone: "13800000000"      # 可选,默认 "13800000000"

Scenario: 配置文件完整提供

  • WHEN config.yaml 中配置了 default_admin
  • AND 提供了 usernamepasswordphone 三个字段
  • THEN 系统读取配置文件的值
  • AND 不使用代码默认值
  • AND 创建管理员账号时使用配置的值

Scenario: 配置文件部分提供

  • WHEN config.yaml 中配置了 default_admin
  • AND 只提供了部分字段(如只配置了 password
  • THEN 系统对已提供的字段使用配置值
  • AND 对未提供的字段使用代码默认值
  • AND 例如:配置了 password: "MySecret123",但未配置 usernamephone
    • 使用 password = "MySecret123"
    • 使用 username = "admin"(代码默认值)
    • 使用 phone = "13800000000"(代码默认值)

Scenario: 配置文件未提供

  • WHEN config.yaml 中未配置 default_admin
  • THEN 系统使用代码内置默认值
  • AND 用户名为 admin
  • AND 密码为 Admin@123456
  • AND 手机号为 13800000000

Scenario: 配置验证

  • WHEN 读取 default_admin 配置
  • THEN 配置项为可选,不参与 Validate() 验证
  • AND 允许配置为空或不存在
  • AND 不阻止服务启动

Requirement: 默认管理员安全配置

系统 SHALL 使用足够复杂的默认密码,并记录管理员创建日志用于安全审计。

Scenario: 默认密码复杂度

  • WHEN 创建默认管理员账号
  • THEN 代码内置默认密码 SHALL 满足以下复杂度要求:
    • 长度 ≥ 12 位
    • 包含大写字母、小写字母、数字、特殊字符
    • 示例:Admin@123456

Scenario: 审计日志记录

  • WHEN 创建或跳过默认管理员账号
  • THEN 系统记录审计日志到 app.log
  • AND 日志包含以下信息:
    • 操作时间
    • 操作结果(创建成功/跳过/失败)
    • 创建的用户名(成功时)
    • 配置来源(配置文件/代码默认值)
    • 失败原因(失败时)
  • AND 不在日志中记录明文密码

Requirement: 系统账号创建内部接口

Account Service SHALL 提供内部方法用于系统初始化场景创建账号,绕过常规的用户上下文检查。

Scenario: 系统初始化创建账号

  • WHEN 系统初始化需要创建内部账号(如默认管理员)
  • THEN 调用 createSystemAccount(ctx, account) 方法
  • AND 该方法不检查当前用户 ID允许 context 中无用户信息)
  • AND 保留用户名和手机号唯一性检查
  • AND 密码使用 bcrypt 哈希存储
  • AND 自动设置 creator 和 updater 为 0系统创建

Scenario: 常规 API 请求不使用系统接口

  • WHEN 通过 HTTP API 创建账号
  • THEN 使用常规 Create() 方法
  • AND 必须有当前用户上下文user_id > 0
  • AND 不允许调用 createSystemAccount() 方法(内部使用)