# 前端接口调整说明:同设备三方登录免绑手机号(029) **后端分支**: `test`(`cb8721b` 起) | **日期**: 2026-09-20 > 一句话:登录请求多传一个可选字段 `deviceId`;三方登录多一种返回分支 `deviceConfirm`,弹只读确认框后调一个新接口即可,全程免短信。 ## deviceId 字段说明 - 字符串,**可选**,长度 ≤64,所有接口通用同一个值; - 前端自行生成并持久化(建议:首启生成 UUID 长期保存,尽量卸载重装后不变,如 iOS 存 Keychain / Android 用 ANDROID_ID——具体实现前端自定); - **不传 = 与现在完全一致**,老版本 App 无影响。 --- ## 一、调整的 3 个现有接口(各加 1 个可选参数) ### 1. `POST /infouser/user/lodeing`(手机号+验证码登录) ```json { "phone": "0987654321", "code": "123456", "deviceId": "a3f8c2d4..." } ``` 返回不变。传了 `deviceId` 后,后端会记住"这台设备验证过这个手机号",之后三方登录才能免绑。 ### 2. `POST /infouser/user/oauthLogin`(三方登录) ```json { "provider": "apple", "credential": "", "deviceId": "a3f8c2d4..." } ``` **返回由 2 种变 3 种**(`data` 内容判断): | `data.status` | 含义 | 前端处理 | |---|---|---| | 无(直接返回 `token`+用户) | 三方身份已绑定 | 现状不变,直接登录 | | `"needPhone"` + `tempKey` | 未绑定,设备无信任 | 现状不变:弹手机号+短信绑定 UI → `oauthBindPhone` | | `"deviceConfirm"` + `tempKey` + `maskedPhone` **新增** | 未绑定,但本设备验证过手机号 | 弹确认框(见下)→ 确认后调新接口 `oauthDeviceConfirm` | `maskedPhone` 为脱敏手机号(如 `098****4321`),**只读展示用,不要提交**。 ### 3. `POST /infouser/user/oauthBindPhone`(三方绑手机号) ```json { "tempKey": "xxx", "phone": "0987654321", "code": "123456", "deviceId": "a3f8c2d4..." } ``` 返回不变,传 `deviceId` 只是为了让后端记录设备信任。 --- ## 二、新增 1 个接口:`POST /infouser/user/oauthDeviceConfirm` 用于 `deviceConfirm` 分支的一键确认(免短信)。 **入参**: ```json { "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](contracts/api-contract.md)。