跳转到正文
图奕科技 开发文档 平台登录
接入指南 / 存量账号映射下载本章 Markdown ↓

本实例 Issuer https://platform.too1.net

存量用户与业务身份映射

原则

网云穿用户原来的隧道、设备、套餐、余额/订单、权限等仍由网云穿数据库管理。本轮平台接入不能重新生成一套业务用户 ID,再把老用户当新用户处理。

  • 平台长期身份键为 (issuer, sub)。
  • 产品原用户 ID 作为不透明字符串使用,前导零和超出 JavaScript 安全整数范围的 ID 都不能丢失。
  • 产品代码固定 wyc;服务端不能接受客户端提交任意产品代码来切换身份。
  • 不迁移旧密码;已有手机号必须由业务方确认可信,正式导入需要显式确认。
  • 一个手机号不代表可以自动合并同一产品的多个历史账号,冲突须隔离处理。

导入文件

UTF-8 CSV 固定表头:

product_code,external_user_id,phone_e164,display_name,source_created_at
wyc,000123456,+8613800000000,示例用户,2024-01-02T03:04:05+08:00

手机号采用 E.164;示例不是待导入的真实用户。先在隔离环境使用脱敏/合成数据演练,真实导出文件按个人信息保护要求保存,不提交 Git、不暴露在公开文档目录。

两阶段 CLI 操作

以下命令由平台运维执行,不是开放给产品任意写入映射的 HTTP API。

# 默认仅校验并生成脱敏报告
./ssoctl users import --file wyc-users.csv

# 核对 Dry Run 报告后,在正确的数据库配置下执行
./ssoctl users import --file wyc-users.csv \
  --apply --trust-all-phones \
  --sha256 SHA256_FROM_DRY_RUN

Dry Run 与 Apply 必须使用同一文件;文件变动需重新核对 SHA256。正式执行前备份、核对目标库,保留导入批次和报告。执行后复核成功数、冲突数与总数,抽查产品 ID 映射,并重复执行确认不会新增重复账号。

处理规则

输入情况 平台处理
合法、唯一手机号且不存在平台账号 创建 pending_activation 用户并预建映射
已有平台手机号 附加产品映射,仍须核对原绑定
同产品重复手机号 隔离冲突,不自动合并
同外部 ID 对应不同手机号 隔离冲突
空/非法手机号 隔离,不能导入成正常用户
同批次重跑 幂等续跑,不重复创建

预建用户没有密码,也没有被伪造的协议接受记录。首次仍须短信或微信认证、接受当前协议,之后才从 pending_activation 激活并继续原授权事务。

若某产品开启“强制绑定微信”,手机号预导入和短信认证仍不会伪造微信身份。用户必须实际完成公众号扫码,并验证预导入的原手机号后才可完成该产品授权;身份冲突继续进入隔离流程,不自动生成或合并账号。

产品回调如何绑定

Client 配置了 product_code=wyc 且用户存在该产品映射时,已验证的 ID Token / UserInfo 可能包含:

{
  "sub": "00000000-0000-4000-8000-000000000001",
  "tuyi_product_code": "wyc",
  "tuyi_product_user_id": "000123456"
}

产品服务端按顺序处理:

  1. 先完整验证 OIDC 身份,不能仅解码 JWT,也不能相信客户端转述的 claims。
  2. 已有 (issuer, sub) 绑定时,使用该业务用户;若与新声明的旧 ID 矛盾,拒绝并记录冲突。
  3. 无绑定但有本产品旧 ID 声明:查找对应老业务用户,检查未被另一个 sub 绑定;在数据库事务中加唯一约束后建立映射。
  4. 没有旧 ID 声明:不能直接推断这是新用户,也可能是未导入或导入冲突的老用户。迁移期先走核查/补全流程,再按产品明确的新注册策略处理。
  5. 绑定成功后用原业务用户 ID 创建产品会话,不改资产归属。

建议产品映射表至少对 (issuer, sub) 和本业务用户 ID 建立符合业务的一对一唯一约束;重复回调和并发首次登录只能建一条映射。

放量与回滚

先完成两次隔离演练,再内部账号、1%、10%、30%、100% 分阶段放量,每阶段观察业务高峰。旧登录入口及回退开关保留,出现映射错误立即停止放量,不在线执行自动账号合并。

手机号改变、禁用及会话撤销通过签名事件通知产品,但产品仍需撤销自己的会话。恢复演练需确认平台用户、映射和产品业务资产一致;不能只验证“数据库能启动”。