Files
story/openapi/mini.yaml
T

208 lines
11 KiB
YAML
Raw Normal View History

openapi: 3.1.0
info:
title: 小程序原生登录与自动蓝牙连接
version: 2.0.1
description: HTTPS;POST 必须携带 UUID v4 X-Request-ID。响应使用 ok/code/request_id/server_time_ms/data 信封。不发 Cookie,不使用 AppSecret 或云开发。现有网页 Origin/CSRF 规则不变。
paths:
/api/v1/mini/login/session:
post:
summary: 创建20分钟原生登录会话
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [portal]
properties:
portal: {type: string, enum: [customer, operator]}
responses:
'200': {description: 'data: {login_token: realm.opaque, expires_in: 1200, sms_enabled: boolean}'}
default: {description: 参数错误、限流或服务异常}
/api/v1/mini/login/captcha:
post:
summary: 获取图形验证码
security: [{MiniLogin: []}]
requestBody: {$ref: '#/components/requestBodies/Empty'}
responses:
'200': {description: 'data: {captcha_id, image: PNG data URL, expires_at_ms}'}
default: {description: 登录会话失效或限流}
/api/v1/mini/login/password:
post:
summary: 使用已有手机号密码登录,不自动注册或提升权限
description: 设备未通过短信验证或验证已过期时返回 403 NEW_DEVICE_SMS_REQUIRED。先完成 LOGIN 短信验证,再将返回的 trusted_device_token 按服务地址、账号和 portal 保存在客户端,后续密码登录携带。设备验证最长 30 天,不代替密码或人机验证。
security: [{MiniLogin: []}]
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}
password: {type: string, maxLength: 256}
trusted_device_token: {type: string, maxLength: 43, writeOnly: true}
captcha_id: {type: string, format: uuid}
captcha_code: {type: string, pattern: '^[0-9]{6}$'}
captcha_ticket: {type: string, maxLength: 4096, writeOnly: true}
responses:
'200': {description: 'data: {access_token: realm.opaque, portal: customer|operator, expires_in: 86400};会话只能成功消费一次'}
default: {description: 验证码或密码错误、账号不可用或限流}
/api/v1/mini/login/sms/send:
post:
summary: 小程序发送手机号登录验证码
description: 与 SaaS 网页、设备绑定入口共用腾讯云短信通道、手机号发送限额和 6 位验证码规则;需先调用 login/captcha。不会返回验证码。
security: [{MiniLogin: []}]
requestBody:
required: true
content:
application/json:
schema: {$ref: './onboarding.yaml#/components/schemas/SMSSendInput'}
responses:
'200': {description: 'data: {sms_challenge_id, expires_at_ms, resend_after_ms}'}
default: {description: 图片验证码错误、发送失败、登录会话失效或限流}
/api/v1/mini/login/sms/verify:
post:
summary: 小程序验证短信并获得原生登录令牌
description: 客户可按唯一自注册租户配置创建普通账号;管理账号必须预先绑定手机号。挑战与小程序登录会话绑定,成功后一次性消费,不发 Cookie。成功响应另含 trusted_device_token 和 trusted_device_expires_in(2592000 秒),供此设备后续密码登录使用。
security: [{MiniLogin: []}]
requestBody:
required: true
content:
application/json:
schema: {$ref: './onboarding.yaml#/components/schemas/SMSVerifyInput'}
responses:
'200': {description: 'data: {access_token: realm.opaque, portal: customer|operator, expires_in: 86400}'}
default: {description: 验证码错误、过期、账户不可用或登录会话失效}
/api/v1/mini/account:
get:
summary: 校验原生登录状态
security: [{Mini: []}]
responses:
'200': {description: 'data: {authenticated: true, portal, display_name}'}
default: {description: 登录已过期、撤销或账号被停用}
/api/v1/mini/logout:
post:
summary: 撤销当前原生会话
security: [{Mini: []}]
requestBody: {$ref: '#/components/requestBodies/Empty'}
responses:
'200': {description: 'data: {signed_out: true}'}
default: {description: 登录失效或服务异常}
/api/v1/mini/ble-session:
post:
deprecated: true
summary: 自动建立设备加密连接,无需手动输入设备编号或配网密码
security: [{Mini: []}]
description: 仅允许有设备租户内家庭管理权限的家庭账号和未绑定设备。验证设备随机连接证明,返回本次连接专用 SRP 密码;绝不返回工厂密钥或标签配网密码。
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [device_id, model, key_version, client_nonce, server_nonce, proof]
properties:
device_id: {type: string, pattern: '^KP01-[0-9A-F]{12}$'}
model: {type: string}
key_version: {type: integer, minimum: 1}
client_nonce: {type: string, pattern: '^[A-Za-z0-9_-]{22}$'}
server_nonce: {type: string, pattern: '^[A-Za-z0-9_-]{22}$'}
proof: {type: string, pattern: '^[a-f0-9]{64}$'}
responses:
'200': {description: 'data: {device_id, model, session_password: 64字符小写十六进制};只在当前蓝牙连接内有效'}
default: {description: 设备或家庭权限不满足、重放证明或绑定暂停}
/api/v1/mini/ble-device-state:
post:
summary: 查询设备账号归属及管理权限;未添加的设备不要求家庭或老人(明文BLE v2)
description: 按实际失败条件返回独立 code 和中文 message,不再合并为 DEVICE_UNAVAILABLE。错误信封含 ok=false、code、message、request_id;不包含其他账号身份或老人资料。详见 docs/device-ble-errors-20260918.md。
security: [{Mini: []}]
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [device_id]
properties:
device_id: {type: string, pattern: '^KP01-[0-9A-F]{12}$'}
responses:
'200': {description: 'data: {device_id, id: 平台设备UUID, model, bound: boolean};bound表示已有账号或老人归属,true时只更新Wi-Fi,不申请bind_token'}
'400': {description: 'DEVICE_ID_INVALID:设备编号格式错误'}
'403': {description: 'ACCOUNT_NOT_FOUND / ACCOUNT_DISABLED / ACCOUNT_DELETED / CUSTOMER_REQUIRED / DEVICE_TENANT_MISMATCH / TENANT_INACTIVE / DEVICE_REVOKED / DEVICE_LOST / DEVICE_QUARANTINED / DEVICE_OWNED_BY_OTHER_ACCOUNT / DEVICE_MANAGE_PERMISSION_REQUIRED;message 提供具体原因及处理方式'}
'404': {description: 'DEVICE_NOT_REGISTERED:平台没有该设备的注册记录'}
'409': {description: 'DEVICE_NOT_RELEASED:尚未出厂放行;DEVICE_ENROLLMENT_UNSUPPORTED:尚未启用蓝牙实体确认绑定;DEVICE_BINDING_STALE:归属记录与当前设备状态不一致'}
default: {description: 参数错误、登录失效、限流或服务异常}
/api/v1/device/ble-state:
post:
summary: 设备用工厂HMAC查询自身是否已绑定,只读,不改变归属
security: [{DeviceHMAC: []}]
requestBody: {$ref: '#/components/requestBodies/Empty'}
responses:
'200': {description: 'data: {bound: boolean};设备仅在true时保存空bind_token任务的新Wi-Fi'}
default: {description: 工厂鉴权失败、设备不可用、限流或服务异常}
/api/v1/mini/ble-bind-tokens:
post:
summary: 为当前客户账号签发5分钟设备绑定令牌,无需先创建家庭或老人
description: 设备和账号校验使用与 ble-device-state 相同的具体错误码及提示。另有 ELDER_ID_INVALID(400,显式老人编号格式错误)及 ALREADY_BOUND(409,已有归属,无需重复添加)。
security: [{Mini: []}]
requestBody:
$ref: './ble-binding.yaml#/paths/~1api~1v1~1web~1ble-bind-tokens/post/requestBody'
responses:
'200': {description: 'data: {bind_token};设备已有归属或使用者无管理权限时拒绝'}
default: {description: 请求无效、登录失效、权限不足或限流}
/api/v1/mini/ble-bind-status:
post:
summary: 查询当前账号签发的绑定令牌结果
security: [{Mini: []}]
requestBody: {$ref: './ble-binding.yaml#/components/requestBodies/Token'}
responses:
'200': {description: 'data: {status: pending|success|failed, message?};蓝牙断开后仍可查询'}
default: {description: 请求无效、登录失效或令牌不可访问}
/api/v1/mini/device-subject:
post:
summary: 将已添加到当前账号的设备绑定给有管理权限的老人
security: [{Mini: []}]
parameters:
- in: header
name: X-Request-ID
required: true
schema: {type: string, format: uuid}
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [device_id, elder_id, expected_account_binding_id]
properties:
device_id: {type: string, format: uuid, description: 设备列表中的平台UUID,不是工厂编号}
elder_id: {type: string, format: uuid}
expected_account_binding_id: {type: string, format: uuid, description: 设备列表返回的account_binding_id}
responses:
'200': {description: 'data: {status: success, device_id, elder_id};同一有效归属和同一老人可安全重试,不重复注册火山'}
'403': {description: 非设备归属账号、无老人管理权限、跨组织或归属已失效}
'409': {description: 设备有待确认操作或升级}
default: {description: 参数错误、登录失效、限流或服务异常}
components:
securitySchemes:
DeviceHMAC: {type: apiKey, in: header, name: Authorization, description: 'Device-HMAC-SHA256 hex;还需X-Device-ID、X-Key-Version、X-Timestamp-Ms、X-Nonce、X-Request-ID,详见docs/device-mini-ble-v2.md'}
Mini: {type: apiKey, in: header, name: Authorization, description: 'Mini 后接 customer.或operator.开头的原生access_token。业务接口仍按原资源白名单和服务器权限验证。'}
MiniLogin: {type: apiKey, in: header, name: Authorization, description: 'MiniLogin 后接 login_token,仅允许验证码和密码登录接口。'}
requestBodies:
Empty:
required: true
content:
application/json:
schema: {type: object, additionalProperties: false}