星线智联接入流程
智联的接入方是 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 的路由配置理解为允许无限并发请求。
浏览器与手机的操作次序
- 原浏览器取得 CSRF 后 start,内存保留 receiverToken、服务端 expiresAt 和两位 verificationCode。仅把服务端允许的 launchUrl 用于微信唤起,不拼接任意外部网址。
- 确认页校验 scanToken 后只执行一次 wx.login,将 code 与扫描证明传给 inspect。缺失、非法参数时不执行 wx.login,不调用后端。
- 服务端先锁定 receiver,再锁扫描证明,消费 scan 后才调用微信交换。交换成功返回短时 approvalToken;扫描证明已用,不能因页面刷新自动重放。
- 小程序验证 targetOrigin 必须精确等于账户 HTTPS 来源,verificationCode 为两位数字字符串,expiresAt 为正的安全整数毫秒值,展示后才允许用户决定。
- 用户点击确认或取消,发出一次 decide;decision 只能
approve或deny。响应应与本次决定匹配。小程序结束后提示手动返回原浏览器。 - 原浏览器按间隔读取 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 开发上传不能替代这些回执,暂停流程需另行恢复。范围说明见技术概览。