# 需求:社交登录与第三方账号绑定(Google/X/微信评估)

> 人工兜底建票(2026-10-04,demand.py new 的 --from 校验仅认 zhihu 台账,boss 会话直投无台账锚点;字段行已按顶格形态)
状态: accepted(2026-10-04 boss 10-04 拍板:Google/X 先做,微信挂起(ICP 备案门槛+海外用户群,provider 接口留位);批次1=Google UI 接线+绑定解绑,批次2=X 适配代码先行(密钥到位即激活))
归属: pinnadash 产品
来源: boss 直投(2026-10-04 boss 会话提出:要 Google/X/微信社交账号登录,「我的账号 id 是标准的,其他社交 id 绑定到我的 id 上面」,后台提供官方绑定/解绑流程)
日期: 2026-10-04
建议: 做,分三批——批次1(Google)只差 UI 接线+secret 配置,零新依赖;批次2(X)等 boss 开发者账号;微信卡 ICP 备案挂起待拍板

## 现状

- 账号模型已是「主账号+社交身份挂靠」标准形态:`users` 表 email 唯一自然键 + `auth_identities`(provider, provider_uid, user_id, 0001 建表,FK 级联删除),`linkIdentity` upsert 已实现;design.md §4 口径「第三方登录身份(Google 等)……两个登录通道归一到同一行」
- **Google OAuth 后端全链路已实现**(`/v1/auth/google` 发起 + callback 换 profile + email 归一合并 + 签发 exchange code + 种 SSO 会话,`oauth.ts` 封装,KV `gstate:` 暂存 state),但生产 secret 未配置(2026-10-04 实测线上带合法参数回 503 Not configured)
- 门户 UI 零接线:登录页(`portal/login/index.html`)无社交按钮,账户中心(`portal/index.html`)账户安全面板无第三方账号绑定管理
- X(Twitter)/微信:零代码零配置。X OAuth2 默认不回传 email,微信只有 openid/unionid——均无法走 email 归一合并,需「无邮箱身份引导绑定」流程
- 微信硬门槛:微信开放平台网站应用(扫码登录)要求域名已 ICP 备案+开发者资质认证 300 元/年;pinnadash.com 托管 CF Pages 海外无备案 → 现状做不了,只可留接口

## 方案

账号模型沿用现有,零 schema 破坏(migration 0010 至多补 user_id 索引+provider 元数据列):

1. **登录·已绑定**:社交回调 → 查 `auth_identities` → 命中即按现有链路签发 exchange code + SSO 会话 → 深链回产品;**五桌面产品零改动**(浏览器侧多一种认证方式,PKCE+深链不变)
2. **登录·未绑定**:引导页「登录/注册你的邮箱账号,完成后自动绑定该社交账号」——保住 email 唯一自然键,天然兼容 X/微信无邮箱场景
3. **绑定/解绑(官方流程)**:账户中心 → 账户安全面板新增「第三方账号」组:已绑列表+绑定按钮(跳 provider OAuth,回调写当前会话用户而非 email 合并)+解绑(`<dialog>` 确认+守卫:邮箱魔法链接永远兜底);admin 后台用户详情顺带只读展示绑定列表
4. **provider 泛化**:`oauth.ts` 扩多 provider 适配器(X=OAuth2+PKCE,微信=openid/unionid+内嵌二维码),路由泛化 `/v1/auth/:provider`;沿用现仓惯例:未配密钥 503 fail-closed、回调参数入 HTML 前转义、KV stash state、测试走真实 SQLite migrations 先红后绿

## 验收标准

> 2026-10-04 进度:全链路已落码并部署上线(api 16ac2b81/admin 6b7ee00e,八项线上验证过,providers 空数组=按钮 fail-closed 不渲染零坏面);①②③等 boss 密钥两对(Google OAuth Client + X developer app),wrangler secret put 即活。

- [ ] 登录页出现 Google 按钮,线上真机走通「Google 一键登录 → 深链回产品」(等密钥)
- [ ] 账户中心可绑定/解绑 Google 账号;解绑后邮箱魔法链接仍可登录(守卫生效)(等密钥)
- [ ] 已绑定用户经 Google 登录与魔法链接登录归一到同一 user id(订阅/会员随号走)(等密钥)
- [x] 未配置密钥的 provider 返回 503 fail-closed,登录页不白屏(2026-10-04 线上实证:providers 空数组/google+X 503/wechat 404)
- [x] 先红后绿测试(真实 SQLite migrations):绑定冲突(社交号已绑其他账号)/解绑守卫/伪造 state 拒绝(social-identity.test.ts 16 条,api 193 全绿,变异抽查红)

## boss 侧格子(需 boss 本人操作/拍板)

1. **Google Cloud Console** 建 OAuth Client(Web 应用),回调 URI 填 `https://account.pinnadash.com/v1/auth/google/callback`,拿 Client ID/Secret 交 agent 配 `wrangler secret put`(凭据不落盘)
2. **X 开发者账号**:developer.x.com 建 app 启用 OAuth 2.0,回调填 `https://account.pinnadash.com/v1/auth/x/callback`,拿 Client ID/Client Secret
3. **微信拍板**:做 = 需国内备案域名 + 300 元/年认证(周期约 2~4 周);不做 = 挂起,provider 接口留位
