7.7 KiB
7.7 KiB
后台管理服务设计
日期:2026-04-23
1. 目标
为当前 Rust api-server 增加一套同源后台管理服务,满足以下首版目标:
- 支持管理员用户名密码登录。
- 支持独立的管理员鉴权,不允许普通玩家 JWT 越权访问。
- 支持在后台查看当前服务与数据库概览信息。
- 支持在后台测试当前
api-server已挂载接口。 - 保持首版工程足够轻量,不新建额外独立服务进程,不引入第二套前端工程。
2. 背景与约束
当前仓库已具备:
- Rust
api-server主链。 - 基于 JWT + refresh session 的普通用户登录体系。
SpacetimeDB + spacetime-client的主数据面。
本次后台管理服务必须继续遵守:
- 后端统一落在
server-rs,不回退到server-node。 - 不额外新起独立管理服务进程。
- 首版以“一个受保护管理域 + 一个同源后台页面”为落地形态。
- 数据库信息必须尽量读取真实数据库侧信息,不能只展示硬编码假数据。
3. 首版范围
3.1 包含
GET /admin:后台管理页面入口。POST /admin/api/login:管理员用户名密码登录。GET /admin/api/me:当前管理员会话信息。GET /admin/api/overview:服务与数据库概览。POST /admin/api/debug/http:受控 HTTP 接口调试。- 基于 Bearer JWT 的管理员鉴权中间件。
3.2 不包含
- 多角色管理员体系。
- 管理员 refresh cookie / 多端会话管理。
- 后台直接写库、删库、执行 reducer。
- 任意 SQL 执行器。
- 新建独立 React/Vite 管理端工程。
4. 总体方案
4.1 部署形态
后台管理服务直接挂载在现有 server-rs/crates/api-server 内,作为同一个 Axum 进程的一部分。
原因:
- 当前
api-server已具备配置、JWT、错误包裹、日志与同源路由能力。 - 后台本质上是服务运维与调试面,不值得单独再起一个网关或 BFF。
- 同源可以避免开发期额外 CORS 和 cookie 域问题。
4.2 页面形态
后台管理页面采用 api-server 直接返回一份内嵌 HTML/CSS/JS 的管理页。
原因:
- 首版目标是“可用的后台能力”,不是新建一套复杂前端基建。
- 管理页面交互相对简单,直接内嵌更易随服务端一起部署。
- 可以避免新增构建链和静态资源发布路径。
4.3 数据库信息来源
数据库概览不走本地 CLI shell,也不依赖前端直接访问数据库。
首版采用两类信息源:
- 服务端配置与连接信息:来自
api-server当前AppConfig。 - SpacetimeDB 真正的数据库元信息与表行数:由
api-server通过 SpacetimeDB 官方 HTTP API 读取。
读取口径:
/v1/database/{database}:读取数据库基础信息。/v1/database/{database}/schema:读取 schema 信息。/v1/database/{database}/sql:对受控表执行SELECT COUNT(*)统计。
说明:
- 首版只做只读概览,不暴露任意 SQL 输入。
- 表清单由后端显式维护,避免用户在后台拼接任意查询。
5. 管理员鉴权设计
5.1 管理员账号来源
首版不复用普通玩家账号仓储,不把管理员账号混进 module-auth 用户表。
管理员账号来自环境变量:
GENARRATIVE_ADMIN_USERNAMEGENARRATIVE_ADMIN_PASSWORD
原因:
- 管理员是平台运维身份,不等于玩家账号。
- 首版目标是尽快落地可靠后台,不引入额外管理员表迁移。
- 环境变量方案最适合当前阶段的单后台入口。
5.2 管理员 JWT
后台登录成功后签发独立管理员 Bearer JWT。
claims 设计:
- 继续复用
platform-auth::AccessTokenClaims。 roles固定包含admin。sub使用稳定管理员主体,例如admin:<username>。sid使用后台会话 ID。- 不写 refresh cookie。
5.3 权限校验
新增 require_admin_auth 中间件,校验规则如下:
- Bearer token 必须可被当前 JWT 配置正确验签。
roles中必须包含admin。sub必须匹配当前管理员配置主体。
普通用户 token 即使同样由本服务签发,只要不带 admin 角色,也一律拒绝访问后台接口。
6. 后台页面设计
首版页面包含三个主区域:
- 登录卡片。
- 数据库概览面板。
- API 调试面板。
交互原则:
- 页面简洁,不默认塞说明性长文案。
- 移动端优先,窄屏下卡片改纵向堆叠。
- API 调试结果在独立结果面板展示,不在按钮下方临时插一段文本。
7. 数据库概览设计
GET /admin/api/overview 返回以下信息:
- 当前服务监听信息。
- 当前
SpacetimeDB server/database配置。 SpacetimeDB数据库基础信息。- 当前 schema 表清单。
- 首批关键表的行数统计。
首批关键表固定覆盖:
runtime_settingruntime_snapshotuser_browse_historyprofile_dashboard_stateprofile_wallet_ledgerprofile_played_worldprofile_save_archivestory_sessionstory_eventbattle_stateinventory_slotquest_recordquest_logtreasure_recordnpc_statecustom_world_profilecustom_world_gallery_entrycustom_world_agent_sessioncustom_world_agent_messagecustom_world_agent_operationcustom_world_draft_cardbig_fish_creation_sessionbig_fish_agent_messagebig_fish_asset_slotbig_fish_runtime_runpuzzle_work_profilepuzzle_agent_sessionpuzzle_agent_messagepuzzle_runtime_runai_taskai_task_stageai_text_chunkai_result_referenceasset_objectasset_entity_binding
返回中的计数失败项必须带错误信息,不能静默吞掉。
8. API 调试设计
POST /admin/api/debug/http 提供一个受控 HTTP 调试代理。
请求参数:
methodpathheadersbody
限制:
- 只允许访问当前服务同源相对路径。
- 调试回环地址由服务端按当前
bind_host解析;若服务监听在0.0.0.0或::,后台自动改走 loopback,避免把通配监听地址直接当成调试目标。 - 禁止调
/admin/api/login本身,避免自套娃。 - 禁止覆盖
host、content-length等危险头。 - 请求超时固定收口。
- 返回调试结果时回显状态码、响应头、响应文本预览。
该能力用于验证当前服务端接口,不等价于通用代理工具。
9. 配置项
新增以下环境变量:
GENARRATIVE_ADMIN_USERNAMEGENARRATIVE_ADMIN_PASSWORDGENARRATIVE_ADMIN_TOKEN_TTL_SECONDS
默认策略:
- 若未配置用户名或密码,则后台登录接口返回
503,后台页面显示“后台未启用”。 - 默认管理员 token TTL 为
4小时。
10. 测试要求
至少覆盖:
- 管理员登录成功。
- 管理员密码错误返回
401。 - 普通用户 token 访问后台接口返回
403。 - 未登录访问后台接口返回
401。 - 后台概览接口在未启用管理员配置时返回
503。 - API 调试接口能成功访问
/healthz。 - API 调试接口拒绝绝对 URL 和后台自身登录接口。
11. 路由清单
首版新增路由:
GET /adminPOST /admin/api/loginGET /admin/api/meGET /admin/api/overviewPOST /admin/api/debug/http
12. 完成定义
满足以下条件时,本任务视为完成:
api-server内存在受保护后台管理域。- 管理员用户名密码可登录。
- 普通用户 token 无法访问后台接口。
- 后台能看到服务和数据库真实概览。
- 后台能调试当前服务 HTTP 接口。
- 路由索引与技术文档已同步更新。