Files
home-automation/docs/design/m3-token-mobile.md
T
tliu93 b359bbe3bf
pytest / test (push) Successful in 54s
docs: add next-phase roadmap, milestone design docs, and CLAUDE.md
- roadmap.md: M1 (DB consolidation) -> M2 (React SPA) -> M3 (token/mobile)
- docs/design/: agent-pipeline design docs with atomic tasks for M1-M3
- CLAUDE.md: workflow, doc map, commit conventions, review-notes briefing flow
- .gitignore: ignore local review-notes/
2026-06-12 15:37:17 +02:00

6.6 KiB
Raw Blame History

M3 — Token 鉴权与移动端(远期试水)

阅读前提:先读 README.md。M3 依赖 M2(已有 /api JSON 契约与 session 鉴权)。

定位:远期、低投入、探索性。React Native 部分主要是"没做过、试试水"。范围可能收缩——其中token 鉴权 + ingestion 端点收口是有持久价值的安全改进,应优先;RN app 是加分项。Orchestrator 可只取前半。

1. 目标

  1. 引入 bearer token 鉴权,让非浏览器客户端(移动端、设备脚本)能安全访问。
  2. 把 M2 暂时维持裸奔的 ingestion 端点POST /location/recordPOST /poo/record)收口到 token 鉴权下。
  3. 做一个 React Native 移动端,用类 OAuth 流程拿 token 后消费现有 /api

2. 现状(M2 完成后)

  • /api/* 走 session cookie + X-CSRF-Token
  • app/services/auth.py 有 server-side sessionauth_sessions 表,token_hash 存储)。
  • POST /location/recordPOST /poo/record无鉴权(设备/脚本裸调用)。

3. 目标架构

3.1 Token 模型

  • 新表 auth_tokensiduser_idtoken_hash(仅存哈希)、label(设备名)、created_atexpires_at(可空=长期)、revoked_at
  • bearer 校验:Authorization: Bearer <token> → 哈希比对 auth_tokens → 命中且未撤销未过期则认定身份。

3.2 类 OAuth 签发流程(无第三方的 Authorization Code 简化版)

  1. 移动端在内置浏览器打开 /authorize?...
  2. 用户账号密码登录(走现有 session),页面展示"授权此设备"。
  3. 批准后服务端生成一次性 authorization code,重定向到 app 深链 homeautomation://callback?code=...
  4. app 用 code 调 POST /api/auth/token 换取 bearer token 并存本地。

简化兜底:批准页直接展示一次性 token 由 app 捕获。优先实现重定向 + code 交换的正规版。

3.3 统一鉴权依赖

  • /api 的数据/CRUD 端点接受session cookie 或 bearer两者之一(同一套端点同时服务 Web 与移动端)。
  • ingestion 端点(location/poo record)改为要求 bearer

3.4 React Native

  • Expo + TypeScript,复用 M2 的 OpenAPI 类型化 client(共享契约)。
  • 内置浏览器走 §3.2 流程拿 token;之后所有请求带 Authorization: Bearer

4. 迁移注意(重要)

  • ingestion 端点一旦要求 bearer现有调用方(HA/设备脚本)必须先配置 token,否则记录会中断。
  • 上线顺序:先签发 token 能力(T01–T02)→ 给现有设备配 token → 再对 ingestion 端点强制 bearer(T03),避免断流。可设一个过渡开关或灰度。

5. 任务依赖图

M3-T01 token 模型 + 迁移
   └─► M3-T02 签发流程(authorize + code 交换)
          └─► M3-T03 统一鉴权依赖 + ingestion 端点收口(含过渡开关)
                 ├─► M3-T04 Web 端 token 管理 UI(列出/撤销设备)
                 └─► M3-T05 React Native app(试水)
                        └─► M3-T06 文档收尾

6. 原子任务(任务卡)

M3-T01 — token 数据模型 + Alembic 迁移

  • Status: todo · Depends: noneM2 完成后)
  • Files: create app/models/token.pyalembic_app/versions/<new>_auth_tokens.pymodify app/models/__init__.pycreate tests/test_token_model.py
  • Acceptance:
    • 迁移在全新库 upgrade 后建出 auth_tokens 表;downgrade 可回滚。
    • token 仅以哈希存储(与 auth_sessions 同等强度),明文不入库。
    • 校验闸门全绿。
  • Reviewer: 哈希算法/长度与现有 session token 一致;expires_at 可空语义明确。

M3-T02 — 签发流程:authorize 页 + code 交换端点

  • Status: todo · Depends: M3-T01
  • Files: create app/api/routes/api/token.pyapp/schemas/token.py;前端 /authorize 页(M2 SPA 内);create tests/test_api_token.py
  • Acceptance:
    • 登录用户在 /authorize 批准后得到一次性 codePOST /api/auth/token 用 code 换取 bearercode 一次性且短时效。
    • 未登录访问 /authorize 跳登录;无效/过期 code 换取失败。
    • 返回的 bearer 仅此一次明文出现,库中只存哈希。
    • 校验闸门全绿。
  • Reviewer: code 一次性、绑定用户、短 TTL;深链 redirect 白名单校验,防开放重定向。

M3-T03 — 统一鉴权依赖 + ingestion 端点收口

  • Status: todo · Depends: M3-T02
  • Files: modify app/dependencies.py(新增"cookie 或 bearer"统一身份依赖);modify app/api/routes/location.pypoo.py(要求 bearer,带过渡开关);modify tests
  • Acceptance:
    • /api 数据/CRUD 端点用合法 bearer 可访问(等价于 session)。
    • ingestion 端点:带合法 bearer 通过,缺/错 token 在强制模式下 401;过渡开关可临时放行(默认关)。
    • 撤销的 token 立即失效。
    • 校验闸门全绿。
  • Reviewer: 过渡开关默认安全(强制);bearer 与 session 两路鉴权不产生绕过;ingestion 行为变更有测试覆盖。

M3-T04 — Web 端 token 管理 UI

  • Status: todo · Depends: M3-T03
  • Acceptance: 在 SPA 内可列出已签发设备 token(label/创建时间/最近使用)、可撤销;撤销后该 token 立即失效;前端闸门全绿。

M3-T05 — React Native app(试水)

  • Status: todo · Depends: M3-T03 · [experimental]
  • Files: create mobile/Expo + TS,复用 OpenAPI 类型化 client
  • Acceptance:
    • 内置浏览器走签发流程拿到 token 并安全存储(Keychain/Keystore)。
    • 至少跑通:登录拿 token → 拉取一类数据展示 → 记一条 ingestion。
    • npm run lint/typecheck/build(或 Expo 等价) 全绿。
  • Reviewer: token 存安全存储而非明文;client 基于共享 OpenAPI 类型。

M3-T06 — 文档收尾

  • Status: todo · Depends: M3-T05
  • Acceptance: README/architecture 增 token 鉴权与移动端说明;roadmap 勾选 M3;openapi/ 同步。

7. 里程碑完成定义(DoD

  • 存在 bearer token 鉴权与签发流程;token 仅哈希存储、可撤销。
  • ingestion 端点已收口到 bearer(过渡完成后强制)。
  • /api 同时支持 session 与 bearer。
  • (加分)React Native app 能拿 token 并消费 /api
  • 后端 + 前端 + 移动端各自校验闸门全绿,openapi/ 入库。

提醒:本里程碑探索性强,T05 可作为独立试水随时叫停,不影响 T01–T04 带来的安全收口价值。