Files
story/openapi/customer-login.yaml
T
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

272 lines
13 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.1.0
info:
title: 家庭端手机号登录
version: 1.1.0
paths:
/api/v1/web/login/session:
get:
operationId: customerLoginSession
summary: 初始化手机号登录页面
description: HTTPS,同源,不接受查询参数。签发 HttpOnly 登录 Cookie 和 CSRF token,20 分钟后过期,同一 Cookie 重载不会轮换 CSRF。短信不可用时仍可使用密码登录。
security: []
responses:
'200':
description: 页面状态;sms_enabled=false 不代表发送成功
headers:
Set-Cookie:
schema: { type: string }
content:
application/json:
schema:
type: object
required: [ok, data]
properties:
ok: { type: boolean }
data:
type: object
required: [sms_enabled, password_enabled, csrf_token]
properties:
sms_enabled: { type: boolean }
password_enabled: { type: boolean }
signup_enabled: { type: boolean }
csrf_token: { type: string }
default: { $ref: '#/components/responses/Failure' }
/api/v1/web/login/sms/send:
post:
operationId: customerSendLoginSMS
summary: 发送家庭端登录验证码
description: 6 位随机验证码,5 分钟有效;每个手机号至少间隔 60 秒、每小时最多 5 次,设备绑定入口共用此限额。同一请求号重试不重复发送。手机号加密、验证码仅存 keyed hash;不在响应中返回验证码。
security: [{ CustomerLoginCookie: [] }]
parameters:
- { $ref: '#/components/parameters/RequestID' }
- { $ref: '#/components/parameters/CSRF' }
requestBody:
required: true
content:
application/json:
schema: { $ref: './onboarding.yaml#/components/schemas/SMSSendInput' }
responses:
'200':
description: 网关已接受发送请求
content:
application/json:
schema: { $ref: './onboarding.yaml#/components/schemas/SMSResponse' }
default: { $ref: '#/components/responses/Failure' }
/api/v1/web/login/sms/verify:
post:
operationId: customerVerifyLoginSMS
summary: 验证验证码并创建家庭端登录会话
description: 验证码只能在发起发送的浏览器会话使用,最多尝试 5 次,成功后一次性消费。已有短信账号复用原身份;仅配置唯一自助注册租户时可自动创建普通客户账号。账号 Cookie 24 小时有效,调用家庭写接口还需 CSRF;不授予运维权限。
security: [{ CustomerLoginCookie: [] }]
parameters:
- { $ref: '#/components/parameters/RequestID' }
- { $ref: '#/components/parameters/CSRF' }
requestBody:
required: true
content:
application/json:
schema: { $ref: './onboarding.yaml#/components/schemas/SMSVerifyInput' }
responses:
'200':
description: 签发 HttpOnly 账号 Cookie,消费匿名登录会话;前端继续读取 /api/v1/me 校验业务账号
headers:
Set-Cookie:
schema: { type: string }
content:
application/json:
schema:
type: object
required: [ok, data]
properties:
ok: { type: boolean }
data:
type: object
required: [csrf_token, data]
properties:
csrf_token: { type: string }
data:
type: object
required: [authenticated]
properties:
authenticated: { type: boolean }
default: { $ref: '#/components/responses/Failure' }
/api/v1/web/login/captcha:
post:
operationId: customerLoginCaptcha
summary: 获取或更换密码登录、发送短信前的人机验证
description: 服务端选择图片、腾讯云或本地拼图滑块模式,不返回答案或目标横坐标。绑定登录 Cookie,2 分钟有效;刷新使旧挑战失效;每次校验均消费验证码。滑块需先调用 captcha/verify,成功票据再随短信或密码请求提交。校验状态保存在 Redis,依赖不可用时拒绝登录。
security: [{ CustomerLoginCookie: [] }]
parameters:
- { $ref: '#/components/parameters/RequestID' }
- { $ref: '#/components/parameters/CSRF' }
requestBody:
required: true
content:
application/json:
schema: { type: object, additionalProperties: false }
responses:
'200':
description: 图片验证码
content:
application/json:
schema:
type: object
required: [ok, data]
properties:
ok: { type: boolean }
data:
type: object
required: [captcha_id, mode, expires_at_ms]
properties:
captcha_id: { type: string, format: uuid }
mode: { type: string, enum: [image, tencent, slide] }
captcha_app_id: { type: string, description: 腾讯云模式对应客户端的公开 CaptchaAppId,不含密钥 }
image: { type: string, pattern: '^data:image/(png|jpeg);base64,' }
thumb_image: { type: string, pattern: '^data:image/png;base64,' }
image_width: { type: integer, minimum: 1 }
image_height: { type: integer, minimum: 1 }
thumb_width: { type: integer, minimum: 1 }
thumb_height: { type: integer, minimum: 1 }
thumb_x: { type: integer, minimum: 0, description: 拼图块的初始展示横坐标 }
thumb_y: { type: integer, minimum: 0, description: 拼图块所在水平轨道 }
expires_at_ms: { type: integer, format: int64 }
default: { $ref: '#/components/responses/Failure' }
/api/v1/web/login/captcha/verify:
post:
operationId: customerVerifyLocalSlideCaptcha
summary: 校验本地滑块位置并换取一次性票据
description: 同源、CSRF 和登录会话校验;挑战每次提交即消费。成功票据绑定原会话、客户端、策略版本和原到期时间,只能用于一次短信发送或密码登录。
security: [{ CustomerLoginCookie: [] }]
parameters:
- { $ref: '#/components/parameters/RequestID' }
- { $ref: '#/components/parameters/CSRF' }
requestBody:
required: true
content:
application/json:
schema: { $ref: './login-captcha.yaml#/components/schemas/SlideCaptchaVerifyInput' }
responses:
'200':
description: 位置正确,返回一次性校验票据
content:
application/json:
schema: { $ref: './login-captcha.yaml#/components/schemas/SlideCaptchaVerifyResponse' }
default: { $ref: '#/components/responses/Failure' }
/api/v1/web/login/password:
post:
operationId: customerLoginPassword
summary: 手机号、密码和图片验证码登录
description: 使用与短信登录一致的手机号身份,密码登录不自动注册。每手机号 10 分钟最多 10 次密码尝试;每登录会话最多 20 次。失败返回统一的手机号或密码错误,不暴露手机号是否注册。密码正确但没有该账号的有效设备验证 Cookie 时返回 403 NEW_DEVICE_SMS_REQUIRED,不消费登录会话、不发账号 Cookie;完成现有 LOGIN 短信验证后签发 30 天 HttpOnly 设备验证 Cookie。已验证设备成功消费登录会话,签发 24 小时账号 Cookie。
security: [{ CustomerLoginCookie: [] }]
parameters:
- { $ref: '#/components/parameters/RequestID' }
- { $ref: '#/components/parameters/CSRF' }
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [phone_e164, password, captcha_id]
anyOf:
- required: [captcha_code]
- required: [captcha_ticket]
properties:
phone_e164: { type: string, pattern: '^\+[1-9][0-9]{7,14}$' }
password: { type: string, minLength: 1, maxLength: 256, writeOnly: true }
captcha_id: { type: string, format: uuid }
captcha_code: { type: string, pattern: '^[0-9]{6}$', writeOnly: true }
captcha_ticket: { type: string, maxLength: 4096, writeOnly: true }
captcha_randstr: { type: string, maxLength: 256, writeOnly: true, description: 腾讯云 Web 模式必填,本地滑块模式无需提供 }
responses:
'200':
$ref: '#/paths/~1api~1v1~1web~1login~1sms~1verify/post/responses/200'
default: { $ref: '#/components/responses/Failure' }
/api/v1/web/account/password:
get:
operationId: customerPasswordState
summary: 查看当前手机号和密码设置状态
security: [{ CustomerAccountCookie: [] }]
responses:
'200':
description: 仅返回脱敏手机号、是否已设置密码、是否具有最近 10 分钟内且未消费的短信验证,不返回密码或摘要
content:
application/json:
schema:
type: object
properties:
ok: { type: boolean }
data:
type: object
required: [available]
properties:
available: { type: boolean }
phone_masked: { type: string }
password_configured: { type: boolean }
sms_verified_recently: { type: boolean }
default: { $ref: '#/components/responses/Failure' }
post:
operationId: customerSetPassword
summary: 设置、修改或重置当前手机号的密码
description: 需要当前有效账号 Cookie、同源及 CSRF;同时需要最近 10 分钟内且未消费的短信验证,或正确的当前密码。新密码 6–64 个 Unicode 字符且不超过 256 字节。修改后清除短信证明并撤销该身份的其他账号和设备绑定浏览器会话,保留本次会话。密码使用随机盐 Argon2id 存储。
security: [{ CustomerAccountCookie: [] }]
parameters:
- { $ref: '#/components/parameters/RequestID' }
- { $ref: '#/components/parameters/CSRF' }
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [password]
properties:
password: { type: string, minLength: 6, maxLength: 64, writeOnly: true }
current_password: { type: string, maxLength: 256, writeOnly: true }
responses:
'200':
description: 密码已保存
content:
application/json:
schema:
type: object
properties:
ok: { type: boolean }
data:
type: object
properties:
password_configured: { type: boolean }
default: { $ref: '#/components/responses/Failure' }
components:
securitySchemes:
CustomerAccountCookie:
type: apiKey
in: cookie
name: __Host-platform-onboarding
description: 仅本地 HTTP 模式使用 platform-onboarding。不能用于运维接口。
CustomerLoginCookie:
type: apiKey
in: cookie
name: __Host-platform-login
description: Secure、HttpOnly、SameSite=Lax;仅本地 HTTP 模式使用 platform-login。
parameters:
RequestID:
in: header
name: X-Request-ID
required: true
schema: { type: string, format: uuid }
description: UUID v4,发送结果未知时用同一 ID 和正文重试。
CSRF:
in: header
name: X-CSRF-Token
required: true
schema: { type: string }
responses:
Failure:
description: 400/401/403/409/413/415/429/500/503;SMS_CODE_INVALID、LOGIN_SESSION_EXPIRED、SMS_RATE_LIMITED、SMS_SEND_UNCERTAIN、SMS_UNAVAILABLE、CAPTCHA_INVALID、CAPTCHA_UNAVAILABLE、PASSWORD_INVALID、PASSWORD_POLICY、CURRENT_PASSWORD_INVALID、SMS_REAUTH_REQUIRED、RATE_LIMITED 等,不返回验证码或密码。
content:
application/json:
schema: { $ref: './onboarding.yaml#/components/schemas/Failure' }