6.9 KiB
/api/auth/login-options 登录方式选项设计
日期:2026-04-21
1. 文档目的
这份文档用于冻结 Rust api-server 首版 GET /api/auth/login-options 的返回 contract、配置来源与当前阶段边界,确保前端在登录页读取“当前可用登录方式”时,不需要依赖硬编码开关。
2. 当前目标
当前阶段只解决一件事:
- 由
Axum根据服务端配置,返回当前环境启用的登录方式列表。 - 密码登录入口由 Rust
password_entry固定承载,作为登录弹窗的保底入口。
本阶段明确不包含:
- 短信或微信登录链路本身是否已经完整落地
- 对前端返回更细粒度的 provider 配置
- 第三方登录按钮文案、图标或 UI 布局规则
3. 接口 contract
3.1 请求
- 方法:
GET - 路径:
/api/auth/login-options - 鉴权:不需要
- 请求体:空
3.2 成功响应
{
"availableLoginMethods": ["phone", "password", "wechat"]
}
字段说明:
availableLoginMethods为字符串数组- 当前阶段只允许出现:
phonepasswordwechat
3.3 返回顺序
返回顺序固定为:
- 先
phone - 再
password - 再
wechat
这样可以保证前端按钮顺序稳定,不因配置解析顺序变化而漂移。
4. 配置来源
api-server 只读取以下布尔配置:
SMS_AUTH_ENABLEDWECHAT_AUTH_ENABLED
映射规则固定为:
SMS_AUTH_ENABLED=true时返回phone- Rust 密码登录主链可用时固定返回
password WECHAT_AUTH_ENABLED=true时返回wechat- 短信与微信都关闭时仍返回
["password"]
5. crate 边界
5.1 api-server
负责:
- 读取
AppState.config - 组装
availableLoginMethods - 返回项目兼容的响应 envelope
5.2 module-auth
本接口当前阶段不依赖 module-auth。
5.3 前端
负责:
- 根据
availableLoginMethods决定是否展示手机号 / 微信入口 - 不再假设某种登录方式一定存在
- 若
/api/auth/login-options联调失败或返回空数组,前端仍保留password入口,避免登录弹窗显示“当前登录入口暂不可用”后无法继续操作。
6. 测试要求
至少覆盖:
- 默认配置下返回
["password"] - 同时启用短信、密码与微信时返回
["phone", "password", "wechat"] - 前端在
login-options读取失败或返回空数组时,仍展示密码登录表单
7. 完成定义
满足以下条件时,本任务视为完成:
- Rust 已提供
GET /api/auth/login-options - 响应字段命名与前端约定一致
- 配置开关可稳定映射到返回数组
- 文档、任务清单与测试已同步更新
8. 2026-05-01 前端降级修复记录
本地联调时若 api-server 未启动或 Vite 代理暂时返回 500,GET /api/auth/login-options 会失败。前端必须继续遵循第 5.3 节约束:
AuthGate在login-options读取失败时设置availableLoginMethods = ["password"]。- 该失败只代表登录方式配置探测失败,不代表登录功能不可用,因此不把
读取登录方式失败写入登录弹窗错误条。 - 登录弹窗仍展示密码登录表单,玩家可继续登录后进入创作链路。
- 本地仍需要启动
api-server,否则后续POST /api/auth/entry等真实登录请求无法完成。
9. 2026-05-07 本地短信入口恢复记录
如果登录弹窗里短信登录页签“像是被删了”,先不要改前端表单,优先检查本地登录方式探测结果:
- 仓库根目录
.env.local里必须显式保留SMS_AUTH_ENABLED=true。 - 本地启动请优先使用
npm run api-server、npm run dev:rust或npm run dev,这些脚本会按“shell 环境优先、.env.local覆盖.env”合并配置。 - 若
GET /api/auth/login-options只返回["password"],说明短信入口没有被服务端配置打开,前端只是按 contract 正常降级。 - 当
SMS_AUTH_ENABLED=true生效时,GET /api/auth/login-options至少应返回["phone", "password"],短信登录页签才会重新出现。
10. 2026-05-07 前端代理端口错配修复记录
如果 Rust API 直连返回 ["phone", "password"],但从前端域名请求 GET /api/auth/login-options 返回 500,短信页签同样会消失。此时不是登录 UI 被删除,而是 AuthGate 按第 5.3 节降级成 ["password"]。
本地排查顺序固定为:
- 先请求
http://127.0.0.1:3000/api/auth/login-options,确认前端代理是否成功返回 JSON。 - 再请求当前 Rust API 目标,例如
http://127.0.0.1:3100/api/auth/login-options或http://127.0.0.1:8082/api/auth/login-options。 - 若直连 API 成功而 3000 返回
500,检查RUST_SERVER_TARGET、GENARRATIVE_API_TARGET、GENARRATIVE_RUNTIME_SERVER_TARGET是否指向仍在监听的 API 端口。 npm run dev/npm run dev:rust完整栈默认由脚本计算 API 端口;加载.env.local给后端使用后,脚本必须重新固定RUST_SERVER_TARGET,避免.env.local中的旧代理目标覆盖本次启动的实际 API 端口。npm run dev:web只启动前端,不会自动拉起 Rust API;如果.env.local/ 当前环境已经显式声明GENARRATIVE_RUNTIME_SERVER_TARGET、RUST_SERVER_TARGET、GENARRATIVE_API_TARGET或GENARRATIVE_API_PORT,脚本必须固定使用该目标。目标当下不可用时只打印警告,不自动切到另一个端口,避免前端进程长时间绑定到随后会停掉的临时 API。- 如果
3000仍然返回500,先确认浏览器是不是还开着旧的前端进程。当前脚本如果因为端口占用漂移到3001/3002,应直接关掉旧进程后重启,而不是继续用旧的 3000 页面判断登录入口状态。
11. 2026-05-10 npm run api-server 环境加载与短信 provider 排查记录
本地单独启动 api-server 时,环境变量合并顺序固定为:
外层 shell > .env > .env.local > .env.secrets.local
这保证 .env.local 能覆盖 .env.example 派生出的默认值,.env.secrets.local 能继续覆盖本地私密密钥配置。scripts/api-server-dev.mjs 不得让 .env 后加载并覆盖 .env.local,否则 SMS_AUTH_ENABLED 或 SMS_AUTH_PROVIDER 可能被压回错误值。
排查“点击获取验证码但手机收不到短信”时,除了确认 availableLoginMethods 包含 phone,还必须确认当前进程实际使用的 provider:
SMS_AUTH_PROVIDER="mock"只用于本地 UI / 账号链路联调,不会向手机发送真实短信;此时应使用SMS_AUTH_MOCK_VERIFY_CODE,默认123456。- 真实短信链路必须使用
SMS_AUTH_PROVIDER="aliyun",并在修改.env.local后重启api-server,运行中的进程不会自动切换 provider。 - 真实 provider 是否被使用,以
api-server日志中的provider=aliyun、provider_request_id和provider_out_id为准。