问题8 登录系统: - node:sqlite 账号存储(scrypt 哈希 + HMAC 签名 token),preset admin 改为 e2hang/evan1115 - /api/auth/register|login|me,me 返回 room 供重联 - 网关拦截 create/join 需登录(401),列表保持开放 踢人逻辑修正(问题2 延伸): - kickMove 真正释放座位(folded=false, name=null)而非锁死 - war/mill 去掉永久封禁语义 管理员越权:管理员 token 可删任意房间、踢任意房间内的人 单房间约束(用户新需求): - 同一用户同时只能在一个房间,create/join 他房返回 409 - 踢人后若房间仅剩踢人者则自动解散并释放其记录(修复 2 人局踢光对手后被困 409) - 陈旧房间记录兜底清理 UI 清理:移除"改名"按钮与"你的名字"输入框;删除房间按钮仅房主/管理员可见 docs: 新增 12-auth-kick-single-room.md 汇总本会话全部需求/根因/修复/边界测试 Co-Authored-By: Claude (CodeBuddy) <noreply@codebuddy.ai>
3.3 KiB
3.3 KiB
问题 8(通用):用户登录系统(名称 + 密码身份)
需求
“可不可以做一个用户登录,用户设置名称和密码然后以这个身份加入。”
即:用户在客户端注册/登录一个账号(名称 + 密码),之后以该身份创建/加入房间。
—— 这是一个跨房间、跨对局的持久身份,区别于当前“每次改名只影响单个房间”的 playerName。
现状
- 当前身份仅为
App.playerName(localStorage里的随机名,可随时改), 进入房间时作为playerName传给 lobbyjoinMatch;无密码、无账号、无服务端校验。 - boardgame.io 的 lobby
join用credentials(server 生成的随机串)鉴权,与“用户密码”无关。
拟采用方案(轻量账号系统,复用现有 server)
后端(packages/server)
新增账号存储 + 登录/注册端点(挂在 /api/auth/...),因 server 是 InMemory(重启丢数据),
账号表也用内存 Map(可接受;如需持久化见下方决策点)。
// 内存表:username -> { passwordHash, salt }
const accounts = new Map<string, { hash: string; salt: string }>();
POST /api/auth/registerbody{ username, password }: 校验用户名长度/字符;用crypto.scrypt加盐哈希;已存在则 409。POST /api/auth/loginbody{ username, password }: 校验哈希;成功返回{ token }(用 HMAC/签名 JWT 或简单签名串,含 username + 过期时间)。- (可选)
GET /api/auth/me用 token 回显 username。
说明:本项目的“身份”主要用于进房时的名字与一致性,不需要 OAuth 级安全。 哈希存储是基本卫生(不存明文密码)。token 用
crypto签名即可,不必引入 jsonwebtoken 依赖。
前端(apps/web + packages/ui)
- 在
App.tsx顶部加“登录/注册”栏(登录态存localStorage:{ username, token })。 - 登录后,把
username作为进入房间时的playerName(替换当前的随机名/手输名)。 - 房间列表
LobbyRoomList的playerName改为取“已登录账号名”(未登录则退回原有输入/随机名)。 - 退出登录清除本地 token。
与问题 1/2 的耦合
- 登录身份 →
playerName→ 进房join(lobby metadata name)。 - 改名(问题 1):登录用户是否允许改名?建议:登录用户以账号名为准,房间内改名仅作用于本房间显示(保持现有 rename move 语义)。
- 房主判定(问题 2):账号体系与“房主”是两回事;房主仍是房间创建者(metadata
createdBy),与登录名无关。
决策点(需用户确认)
- 账号持久化:内存(重启即丢,与现有 InMemory 房间一致)vs 落盘(FlatFile/JSON)。建议先内存,后续可加。
- 安全强度:休闲局域网场景,scrypt + 签名 token 是否足够?还是用户期望真正的会话/多端?
- 是否强制登录:允许匿名(随机名)进入,还是必须登录才能创建/加入房间?建议允许匿名,登录为可选增强。
验证
- 注册 → 登录拿 token → 以该名进房,房间列表 pill 显示账号名。
- 错误密码登录失败;重复注册 409。
- 登录态在刷新后保留(localStorage)。