# 平台调研 01 · 无感多用户身份系统 > 课题:多个玩家(家庭 WiFi 手机/PC + 未来公网 game.xiangsilian.com)可区分、可保留各自进度与设置,且**绝不能强迫注册**。 > 调研日期:2026-09-09。方法:本仓库代码审计 + 业界模式检索(来源链接见 §3.6)。 --- ## 0. 结论速览 **主推:方案 B「自动匿名档案 + 设备档案切换器 + 配对码跨设备」**——首次访问 0 输入 0 点击即自动建档(服务器静默发 token,玩家无感知),同设备多玩家用 Netflix 式档案切换,跨设备/找回用「旧设备出示 6 位配对码 → 新设备输入」;纯静态公网形态自动降级为方案 A(纯本地档案)。PIN 降级为**可选的"认领"升级项**(防兄弟恶作剧),passkey 留给公网化之后再评估(LAN HTTP 下技术上不可用,见 §3.3)。 三个待产品拍板的决策点见文末 §6。 --- ## 1. 现状审计 ### 1.1 服务器(web/server/server.js,310 行) | 项 | 现状 | 评估 | |---|---|---| | 注册/登录 | `POST /api/register {username, pin}` / `POST /api/login`,PIN 4~6 位数字 | **PIN 明文存 users.json**;用户名可中文(`USERNAME_RE`) | | Token | 登录返回 24 字节随机 hex,内存 + sessions.json | **永不过期、无登出端点**——客户端"退出"只是删 localStorage,token 在服务器侧永久有效 | | 进度 API | `GET/PUT /api/progress`,Bearer token,`data` 自由格式但须带 `summary`(大厅卡片显示) | 接口形状健康,可复用 | | 并发 | 按文件串行 Promise 队列,tmp+rename 原子写 | 健康,可复用 | | 防护 | 无速率限制、无 IP 封禁、HTTP 明文 | HANDOVER §2.2 已自我标注"玩具级" | 数据模型(web/server/data/ 实测): ``` users.json { "uuu": "0858" } // username -> pin 明文 sessions.json { "<48位hex>": "uuu" } // token -> username,无过期时间 uuu.json { "_settings": {voice, speed, bgm, guide} } // 一用户一文件 {: data} ``` ### 1.2 客户端(web/index.html + 各游戏) - **登录态**:localStorage `soundgame.auth` = `{username, token}`,大厅与 7 个游戏各自直读此 key。 - **游客态今天就能玩**:不登录 → 全部 8 款游戏可玩,进度写各游戏自己的 localStorage key,设置写 `soundgame.settings`。服务器同步仅在登录时进行(PUT 静默跳过)。**即"本地优先 + 可选账号"架构今天已经成立,只是"账号"这一半摩擦大(要起名+想 PIN+输两遍)且公网不可用。** - **公网形态**(docs/deploy.md):Nginx 纯静态、**不跑任何 API**;大厅检测 `https://*.xiangsilian.com` 即隐藏整个用户面板(index.html `PUBLIC_STATIC`)→ 公网访客全部是孤立的 localStorage 游客。deploy.md 已写明公网开放 API 的前置(127.0.0.1 绑定、只反代 /api/、limit_req、PIN 哈希、token 过期)。 localStorage key 全量清单(多档案方案的现实约束,见 §4): | key | 归属 | 说明 | |---|---|---| | `soundgame.auth` | 大厅+7游戏 | 登录 token | | `soundgame.settings` | engine/settings.js | 四项全局设置 | | `soundgame.progress.rpg` / `.dungeon` / `.radio` | 各游戏 | 存档(命名不统一) | | `soundgame.rhythm.progress` | rhythm | 存档 | | `soundgame.simon.best` / `soundgame.space.best` / `soundgame.escape.stats` | 各游戏 | 最高分/统计 | | `soundgame.rpg.tutIntroSeen` / `soundgame.escape.guideDone` / `soundgame.space.drillDone` | 各游戏 | 一次性教学标记 | | (storyline 无本地 key) | — | 无本地持久化 | ### 1.3 审计发现的关键缺口(新方案必须解决) 1. **跨设备恢复只做了 1/8**:只有 radio 在"本地无存档 + 已登录"时 GET 服务器存档(radio/game.js:325-342);rpg/dungeon/rhythm/escape/simon/space 只 PUT 不 GET——**已登录用户换设备,7 款游戏进度照样丢**(服务器上有副本却不拉回)。 2. **设置是"设备级"而非"玩家级"**:一台手机一个 `soundgame.settings`;家里视障玩家 2.2x 语速与普通玩家 1.0x 共用一部手机时互相覆盖(虽然登录后会拉 `_settings`,但游客态无档案可分)。 3. **大厅无读屏适配**:index.html **零 aria 属性**;登录表单是 JS 动态生成、仅 placeholder 无 `