# App 登录名密码与统一用户 ID 登录交互规则:微信小游戏(含桌面图标)、TapTap内H5、TapTap桌面发行端与桌面快捷入口优先校验/复用有效登录态并自动登录;无有效登录态或平台要求授权时,允许走对应平台官方流程。TapTap可按实际运行环境跳转TapTap客户端或官方登录页,完成后回到游戏;微信小游戏使用其实际微信运行环境允许的官方登录/授权,不擅自改成网站扫码OAuth。需要官方授权不等于登录失败,不禁止必要的官方登录按钮/页面,也不强制每次重复授权。取消、认证失败或读档失败时仅提供实际状态及重新登录/重试,不提供密码、游客、试玩或离线兜底。TapTap桌面发行端仍是taptap/taptap,微信桌面图标仍是wechat/wechat;操作系统和快捷方式不决定登录方式。TapTap小游戏保留平台登录,独立App仍为app/password及登录名密码。后端必须验证真实凭据、会话和进度归属,不信任客户端自报成功;给出前端配合契约,不擅自修改未授权业务工程。 当前App只用loginMethod=password;账号platform固定app,与会话loginMethod分开。以[应用类型与登录规则](应用类型与登录规则.md)为接入要求,不增加微信/TapTap登录。完整配置、绑定及终端授权边界见[平台与登录方式](平台与登录方式.md)。本次不做历史兼容。 当前0.6.0按全新部署使用,所有App账号、注册/登录与会话返回均携带platform=app;用户ID公式不变。platform与认证provider分别记录,不把微信/TapTap游戏账号混入App服务,不做旧账号回填或旧库兼容升级。 ## 默认接入 App 前端仅填写登录名和密码,调用自己的后端;后端持有运行令牌,代理公共服务。不得记录密码、会话或运行令牌日志。没有用户名、昵称、邮箱、手机号、验证码及自助找回密码。 - POST /v1/apps/{appId}/auth/register:{loginName,password},成功返回 {user:{appUserId,appId,loginName},sessionToken,expiresAt}。 - POST /v1/apps/{appId}/auth/login:使用loginMethod=password及相同登录名密码字段;响应另包含本次loginMethod和user.platform。 - POST /v1/apps/{appId}/auth/change-password:{sessionToken,oldPassword,newPassword},成功返回 {changed:true,reauthenticate:true};全部旧会话失效,重新登录。 - POST /sessions/validate 与 /sessions/logout 校验和退出已有会话。业务后端必须先验证用户会话,不信任前端任意 appUserId。 登录名4~32位ASCII英文字母、数字、下划线,规范化成小写;同App唯一,不同App允许同名且互不通用。密码8~128个UTF-8字节,不裁剪、不转大小写,前端确认密码仅作本地校验,不发送额外字段。未知字段被拒绝。 密码用 Argon2id(19MiB、2次、并行度1),每账号16字节安全随机盐;数据库保存带参数的哈希,不保存明文。账号不存在和错误密码统一401 INVALID_CREDENTIALS。重复注册409 LOGIN_NAME_TAKEN。 同App登录每分钟120次、注册和改密各每分钟20次;登录名登录、账号改密另有限制,每15分钟最多5次,成功清除该账号对应计数;数据库记录跨实例共享。达到限制429 AUTH_RATE_LIMIT(Retry-After:60);每个进程最多同时计算2个密码哈希,繁忙503 AUTH_BUSY(Retry-After:1)。App公网入口还应实施自身流量控制,不能将运行令牌交给前端。改密后必须重新登录;没有忘记密码重置接口。 ## 用户 ID 公式:平台分配的2~3位纯小写字母前缀 + 年份末位 + 北京时间MMDD + 6位安全随机数字。 示例:ab61023123456。年份末位每十年循环;ID不能单独作为完整年份或身份认证凭据。随机碰撞由数据库唯一约束和最多32次重试处理。配置 prefix 是应用前缀,不是 app_id,也不是前端输入。 App与游戏共用平台前缀分配台账;账号、会话、数据仍各自隔离。首次开放自动分配前,平台管理员通过 POST /api/admin/user-id-prefixes/import 导入已使用前缀: ~~~json {"confirmExistingPrefixesReviewed":true,"assignments":[{"applicationType":"self_app","applicationId":17,"prefix":"ab"}]} ~~~ 游戏类型使用 self_game,具体身份必须是平台中已有应用。新平台确认没有历史前缀时可用空 assignments 初始化。此接口需管理员凭据,不对App开发AI开放。冲突则整批拒绝,先核对后处理,不能改其他应用来腾前缀。 应用后端自动申请通过后,使用私有身份文件中的SDK凭据访问 GET /api/sdk/applications/{category}/{applicationId}/user-id-prefix;PUT同路径发送 {} 自动分配,或 {"prefix":"ab"} 申请指定前缀。已绑定前缀不可更换;未初始化或冲突返回409,不猜示例前缀。 local仅校验自身数据库前缀绑定;无法离线发现其他服务器的重复配置,所以必须先平台分配。central同时校验集中注册表,不允许本服务内不同App复用前缀。