frontend-guide.md 6.2 KB

前端接口调整说明:同设备三方登录免绑手机号(029)

2026-10-30 增量见文末:同设备换手机号解绑。五字段数据库方案已确认;后端已实现,用户已确认测试库 SQL 执行完成;数据库并发及 App 联调待执行;涉及换号及已有绑定直登的旧描述以增量节为准。

后端分支: test(cb8721b 起) | 日期: 2026-09-20

一句话:登录请求多传一个可选字段 deviceId;三方登录多一种返回分支 deviceConfirm,弹只读确认框后调一个新接口即可,全程免短信。

deviceId 字段说明

  • 字符串,可选,长度 ≤64,所有接口通用同一个值;
  • 前端自行生成并持久化(建议:首启生成 UUID 长期保存,尽量卸载重装后不变,如 iOS 存 Keychain / Android 用 ANDROID_ID——具体实现前端自定);
  • 不传 = 与现在完全一致,老版本 App 无影响。

一、调整的 3 个现有接口(各加 1 个可选参数)

1. POST /infouser/user/lodeing(手机号+验证码登录)

{ "phone": "0987654321", "code": "123456", "deviceId": "a3f8c2d4..." }

返回不变。传了 deviceId 后,后端会记住"这台设备验证过这个手机号",之后三方登录才能免绑。

2. POST /infouser/user/oauthLogin(三方登录)

{ "provider": "apple", "credential": "<idToken>", "deviceId": "a3f8c2d4..." }

返回由 2 种变 3 种(data 内容判断):

data.status 含义 前端处理
无(直接返回 token+用户) 三方身份已绑定 现状不变,直接登录
"needPhone" + tempKey 未绑定,设备无信任 现状不变:弹手机号+短信绑定 UI → oauthBindPhone
"deviceConfirm" + tempKey + maskedPhone 新增 未绑定,但本设备验证过手机号 弹确认框(见下)→ 确认后调新接口 oauthDeviceConfirm

maskedPhone 为脱敏手机号(如 098****4321),只读展示用,不要提交。

3. POST /infouser/user/oauthBindPhone(三方绑手机号)

{ "tempKey": "xxx", "phone": "0987654321", "code": "123456", "deviceId": "a3f8c2d4..." }

返回不变,传 deviceId 只是为了让后端记录设备信任。


二、新增 1 个接口:POST /infouser/user/oauthDeviceConfirm

用于 deviceConfirm 分支的一键确认(免短信)。

入参:

{ "tempKey": "oauthLogin 返回的 tempKey", "deviceId": "本机 deviceId" }

成功:返回结构与 oauthBindPhone 成功完全一致(msg + user + token),按现有登录成功逻辑处理。特殊:若确认期间该三方身份已被其它端绑定,不报错,直接返回 token 登录成功。

失败(code=500,msg 可直接 toast):

msg 含义 处理
登录凭证已过期(tempKey 5 分钟有效) 提示后回登录页,重新点三方登录
设备确认无效(tempKey 不是 deviceConfirm 凭证 / deviceId 不匹配 / 设备无信任) 提示后回登录页
账号已停用 提示账号停用,回登录页

确认弹窗规范:正文"将绑定 {maskedPhone} 并登录",手机号只读不可编辑,弹窗内无手机号/验证码输入框;点"取消"直接关闭,无任何副作用。


三、LINE 登录(网页回调链路):state 传参调整

唯一改动:打开 LINE 授权 URL 时,state 参数从随机串改为传 deviceId:

https://access.line.me/oauth2/v2.1/authorize?...&state={deviceId}

302 回跳参数(com.twanmsdyh.app://oauthLogin?...)由 3 种变 4 种:

参数 处理
token=xxx 现状不变
needPhone=1&tempKey=xxx 现状不变
deviceConfirm=1&tempKey=xxx&maskedPhone=098****4321 新增 弹同款确认框(maskedPhone 记得 URL 解码)→ 调 oauthDeviceConfirm
error=xxx 现状不变

前端自拿 code 走 POST /oauthLogin 的场景:body 带 deviceId 即自动生效,分支同上表。


四、改动清单(速查)

  1. lodeing / oauthLogin / oauthBindPhone 请求体 + deviceId(可选)
  2. oauthLogin 返回新增 deviceConfirm 分支 → 新确认弹窗
  3. 新接口 oauthDeviceConfirm {tempKey, deviceId}
  4. LINE authorize 的 state = deviceId,回跳新增 deviceConfirm=1 分支

字段与错误码细节见 contracts/api-contract.md。

2026-10-30 调整说明(后端已实现,待部署联调)

以本机最新验证登录的手机号为准,包含手机号验证码登录及第三方验证码绑号。后者输入 B 并验证成功时,即使设备原为 A,也直接按 B 完成登录,不用先单独手机号登录。

新版本每个登录/绑定请求都应携带稳定的 deviceId,字段名和 POST body 结构不变。服务端将解除本设备关联的 A 的旧第三方绑定,保留本次新建的 B 绑定;同号登录不解绑,验证失败不解绑。App 登录成功后更新本机会话及清理旧账号第三方登录缓存。

一键确认仍只能确认当前手机号;可另选“使用其他手机号”进入完整验证码绑定。已有第三方绑定与设备当前账号冲突时,不再直接进入旧账号,应先验证码登录对应手机号;旧确认弹窗在设备换号后失效,需要重新发起登录。具体见 contracts/api-contract.md 最新增量节。

LINE 网页回跳新增 error=phone_login_required:提示用户先用对应手机号验证码登录,再重新授权;不要将其当作登录成功。error=fail 仍按失败处理。直连接口错误使用现有 code/msg 包装,不新增请求参数。绑定或确认失败后可能需要重新获取 tempKey,不能无限重放旧凭证。

上线前由后端开发者执行五字段新表 SQL;App 保持同设备稳定的 deviceId。后端不会清理 App 本地缓存,需由 App 在换号成功后替换旧会话并清理旧账号授权缓存。

本次 App 最小改动:用户已确认 deviceId 稳定、失败提示及 tempKey 重启流程已有实现;第三方接口已传相同 deviceId 的前提下,仅需在 lodeing 的 body 补传 deviceId,不增加解绑接口调用。