修复AGC资产读取埋点用户归属
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled

资产读取路由保留可选鉴权并传递已验证 Bearer 主体到响应扩展

补充资产读取主体传递与匿名边界测试

同步 Issue225 技术方案和项目决策记录
This commit is contained in:
2026-09-03 04:56:10 +00:00
parent f28e4b52e7
commit 5e90add1a0
3 changed files with 156 additions and 19 deletions
@@ -166,6 +166,21 @@ ExternalApiPrincipal
本方案不把手机号登录改造成 AGC-only,也不扩大 #225 的 route coverage。
### 6.4 可选鉴权的资产读取路由
`/api/assets/read-url``/api/assets/read-bytes` 同时支持匿名公开素材读取与已登录用户读取,
因此不能直接挂接 `require_bearer_auth`。这两个 handler 会继续使用
`optional_access_token_from_headers` 完成 Bearer 校验和素材权限判断;如果校验成功,
则把同一个已验证的 `AuthenticatedAccessToken` 放入成功响应 extensions,供外层 tracking
middleware 读取真实用户主体。
该传递只发生在当前响应内:
- 匿名公开读取不附加认证主体,仍按 `anonymous` 记录;
- 无效 Bearer 仍返回 `401`,不产生成功 route event
- External API Key 和管理员资产读取继续使用各自的 `ExternalApiPrincipal` / 管理员审计链路;
- 不把 Authorization Header、access token、refresh token 或 Cookie 写入埋点。
## 7. 事件结果示例
### 7.1 AGC 密码登录成功
@@ -244,6 +259,13 @@ HTTP request
- `user_id``owner_user_id``scope_id` 为真实用户;
- outbox metadata 不包含 access token、refresh token、Cookie、密码或验证码。
资产读取的成功链路还必须满足:
- AGC + 有效 Bearer 的 `/api/assets/read-url``/api/assets/read-bytes`route event 的
`user_id``owner_user_id``scope_id` 均为 Bearer 对应的真实用户;
- AGC + 无 Bearer 的公开素材读取仍保持匿名归属;
- 资产读取权限判断和 tracking 主体传递复用同一次 Bearer 校验结果,不重复解析或自行构造身份。
### 9.2 未标记回归
- 未标记手机号登录继续保持既有 route tracking 语义;
@@ -299,7 +321,8 @@ CI 已覆盖的全量测试不要求本地重复运行。
- `server-rs/crates/api-server/src/tracking.rs` 增加 `TrackingLoginSubject`,并将其作为登录主体的最后兜底来源;既有 `ExternalApiPrincipal``AuthenticatedAccessToken` 优先级保持不变。
- `server-rs/crates/api-server/src/password_entry.rs``server-rs/crates/api-server/src/phone_auth.rs` 在认证与 session 创建成功后,仅对合法 AGC marker 请求向 response extensions 附加真实用户主体。
- `server-rs/crates/api-server/src/app.rs` 只在合法 AGC marker 存在时读取该主体并交给 route tracking;未标记请求不使用该新主体来源。
- `server-rs/crates/api-server/src/assets.rs` 保留两个资产读取路由的可选鉴权语义,并在有效 Bearer 成功读取时把已验证主体放入响应 extensions,补齐 AGC 资产读取事件的用户归属;匿名读取和 External API Key/Admin 路由边界未改变。
- `daily_login` helper、event id 幂等、认证响应和 Cookie 语义未修改。
- 已增加密码登录、手机号登录和主体解析测试;两条真实 `build_router → 登录 handler → response extension → tracking middleware → outbox` 链路均验证通过。
- 已增加密码登录、手机号登录、资产读取主体传递和主体解析测试;登录链路与资产读取主体传递均验证通过。
本次实现没有修改 SpacetimeDB schema、migration、bindings、OpenAPI 或后台页面,也没有新增事件 key。