技术文档

星线智联接入流程

智联的接入方是 Account 原浏览器及固定微信小程序,不是任意第三方登录 SDK。所有后端路由使用 https://account.thestarline.cn,路径前缀为 /api/providers/wechat/mobile。资料依据 2026 年 10 月 23 日 identity/server/protocols.ts、wechat-mobile.ts 和 identity/mini-program/lib/ 整理;目前联调暂停、开发上传未审核,完整流程仍待验收。

能力发现与发起条件

GET /api/auth/methods 当前返回 wechatMobile.available。网页应按当前响应显示入口,不根据工程内存在确认页、旧上传记录或单个 enabled 标志判断可用。服务端公众可用判断要求独立小程序配置完整、与网站微信身份不同、enabled、published、launchEnabled 均满足。

发起、状态、取消、领取和绑定是浏览器操作,仍要求 Account 来源、Cookie、CSRF 与上下文绑定。只有小程序 inspect、decide 使用单次证明免除浏览器 Cookie CSRF;若它们携带 Origin,仍只允许账户来源。这不是整个前缀免鉴权。受控预览入口另要求已认证的 Account 管理员及允许的管理登录方式。

方法与完整路径 输入 返回或含义
POST /api/providers/wechat/mobile/start intent:"login" receiverToken,verificationCode,expiresAt,interval,launchUrl
POST /api/providers/wechat/mobile/preview/start intent:"login" 管理员受控路径,返回 previewPath,不返回正式 URL Link
POST /api/providers/wechat/mobile/inspect scanToken,code approvalToken,targetOrigin,browser,verificationCode,expiresAt
POST /api/providers/wechat/mobile/decide approvalToken,decision status:"approved" 或 "cancelled"
POST /api/providers/wechat/mobile/status receiverToken 当前 status,expiresAt
POST /api/providers/wechat/mobile/complete receiverToken 返回 redirect,进入账户登录或待绑定处理,可能设置浏览器 Cookie
POST /api/providers/wechat/mobile/cancel receiverToken 取消尚可取消的事务
GET /api/providers/wechat/mobile/pending 无正文 查询当前浏览器是否有待绑定身份
POST /api/providers/wechat/mobile/bind grantId,以及当前浏览器待绑定 Cookie 将待绑定小程序身份关联到已验证账户

expiresAt 为 Unix 毫秒,interval 单位为秒,当前为 5。服务器状态轮询有单独路由额度,但并不取消全局与来源限额;不要把 160 的路由配置理解为允许无限并发请求。

浏览器与手机的操作次序

  1. 原浏览器取得 CSRF 后 start,内存保留 receiverToken、服务端 expiresAt 和两位 verificationCode。仅把服务端允许的 launchUrl 用于微信唤起,不拼接任意外部网址。
  2. 确认页校验 scanToken 后只执行一次 wx.login,将 code 与扫描证明传给 inspect。缺失、非法参数时不执行 wx.login,不调用后端。
  3. 服务端先锁定 receiver,再锁扫描证明,消费 scan 后才调用微信交换。交换成功返回短时 approvalToken;扫描证明已用,不能因页面刷新自动重放。
  4. 小程序验证 targetOrigin 必须精确等于账户 HTTPS 来源,verificationCode 为两位数字字符串,expiresAt 为正的安全整数毫秒值,展示后才允许用户决定。
  5. 用户点击确认或取消,发出一次 decide;decision 只能 approve 或 deny。响应应与本次决定匹配。小程序结束后提示手动返回原浏览器。
  6. 原浏览器按间隔读取 status,approved 后 complete。完成时再次核对微信绑定与账户凭据版本,并原子消费 receiver,重复领取被拒绝。

合成请求体只表达结构,不能作为实际可用凭据:

{"scanToken":"<本次页面收到的单次扫描证明>","code":"<本次wx.login临时code>"}
{"approvalToken":"<inspect返回且仅保存在页面内存的证明>","decision":"approve"}

这些字符串不应出现在日志、截图、分析事件、setData、Storage 或复制分享内容中。小程序不接收 receiverToken;浏览器不凭 approvalToken 直接换会话。两位核对码只用于人工核对,不是决定接口的身份凭据。

状态机与绑定

服务端状态 浏览器 status 可见值 客户端动作
pending / exchanging / awaiting_confirmation pending 继续有限轮询,等待明确决定
approved approved 原浏览器调用 complete
cancelled cancelled 停止,用户可重新开始新事务
failed failed 停止并报告失败,旧证明不可再用
超过期限 expired 重新开始,不延长本次事务
已消费 receiver 错误响应 不再重复领取

inspect 成功时保存的预期绑定包含当时关联的用户与凭据版本。等待期间有人解绑、改凭据或改变身份关联,complete 会重新检查,防止旧批准继续生效。未绑定身份进入 Account 的后续登录/绑定处理;批准本身不会自动创建一个已验证的业务账户。通用 /api/providers/:provider/start 不是小程序启动入口;移除已绑定身份则走相应 provider/remove,并受重新验证与最后凭据保护约束。

网络与错误处理

API 封装 wx.login 超时为 10 秒,请求超时为 15 秒;服务端访问微信也有限时和响应大小校验。小程序只显示本地固定提示,不原样呈现后端错误内容。调用方可按错误码定位,但不得记录携带的证明。

状态与代码 触发场景 处理
400 INVALID_TRANSACTION 证明格式不符、到期、已消费、状态不允许 返回原浏览器开始新请求
403 CONTEXT_CHANGED 换浏览器领取 使用原发起浏览器,不转发 receiver
403 FORBIDDEN / CSRF_FAILED 非账户来源、管理员门禁或浏览器证明错误 核对来源、会话及能力范围
401 INVALID_CREDENTIALS 等待期间微信绑定已改变 重新验证,不套用旧批准
502 PROVIDER_FAILED 微信交换或 URL Link 获取失败 核对微信平台条件与服务端审计,重新发起
503 PROVIDER_UNAVAILABLE 当前模式未开通 保持入口关闭,不虚报 published

decide 提交后断网或在途跨期为 uncertain,不能自动再次提交批准;服务器可能已接受。检查原浏览器状态后再决定是否开始新事务。页面卸载取消本地请求不代表服务端已经撤销决定;需要原浏览器 cancel 才能按服务端规则改变事务。进入后台也不增加五分钟有效期。

检查与发布范围

在 identity/mini-program/ 可使用 npm test、npm run validate 检查状态机与工程;账号服务测试在 identity/tests/wechat-mobile.test.ts、wechat-mini-adapter.test.ts。开发者工具编译、游客预览和合成 UI fixture 分别验证结构与显示,不能证明真实身份、审批或 Cookie 保持。

正式接入还需核对小程序主体、请求合法域名、独立服务端身份、隐私保护指引、体验与审核可执行入口,以及微信正式 URL Link 能力。现有记录已验证手机批准及原浏览器领取待绑定凭据,仍需完成实际绑定、微信复登与会话保持,再按真实审核号与发布回执记录状态。现有 0.1.0 开发上传不能替代这些回执,暂停流程需另行恢复。范围说明见技术概览。

Markdown 原文完整文档文本