5.9 KiB
5.9 KiB
platform-auth JWT 适配设计
日期:2026-04-21
1. 文档目的
这份文档用于指导 platform-auth 首个真实能力落地,目标是完成:
platform-authcrate 的 JWT claims 结构。- access token 的签发与校验适配。
api-server的最小 Bearer JWT 校验入口。
这一步只解决“Axum 自身能稳定签发并校验 JWT”的基础问题,不提前把 refresh cookie、短信和微信 OAuth 一起耦合进来。
2. 当前落地范围
本阶段只包含以下实现:
JwtConfigAccessTokenClaimsInputAccessTokenClaimssign_access_token(...)verify_access_token(...)api-server的 Bearer 鉴权中间件/_internal/auth/claims内部调试路由
本阶段明确不包含:
- refresh cookie 的生成、解析、轮换和吊销。
- 从
module-auth/SpacetimeDB真相表读取token_version并做在线比对。 - 短信 provider 与微信 OAuth 平台适配。
- SpacetimeDB 模块对 Axum 签发 JWT 的消费代码。
3. 设计输入
本实现直接受以下文档约束:
关键冻结点:
iss/sub/sid/provider/roles/ver/phone_verified/binding_status是当前 access token 的固定字段。sub是稳定user_id。sid是会话 ID,不是单次 token ID。roles当前至少包含user。- 不允许把手机号、openid、风控状态、refresh token hash 放进 JWT。
4. crate 边界
4.1 platform-auth
负责:
- 组织 JWT 结构。
- 执行签名与验签。
- 执行基础 claims 完整性校验。
不负责:
- 用户是否存在。
token_version是否仍是数据库最新值。- refresh session 是否已被吊销。
- provider 之外的业务规则判断。
4.2 api-server
负责:
- 从
Authorization头提取 Bearer token。 - 调用
platform-auth校验。 - 把已校验 claims 写入请求上下文。
- 在本阶段提供最小内部验收入口
/_internal/auth/claims。
不负责:
- 自己再实现一套 JWT 编解码逻辑。
- 把 claims 结构拆散成多个重复 helper。
5. 配置口径
当前阶段 api-server 读取并传入 platform-auth 的配置如下:
| 配置项 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
| issuer | GENARRATIVE_JWT_ISSUER |
https://auth.genarrative.local |
OIDC 风格发行者标识。 |
| secret | GENARRATIVE_JWT_SECRET |
genarrative-dev-secret |
当前阶段沿用对称签名密钥。 |
| access token TTL | GENARRATIVE_JWT_ACCESS_TOKEN_TTL_SECONDS |
7200 |
access token 有效期,单位秒。 |
兼容回退:
issuer可回退读取JWT_ISSUER。secret可回退读取JWT_SECRET。- TTL 可回退读取
JWT_EXPIRES_IN,支持:- 纯秒值,例如
900 s/m/h/d后缀,例如30m、2h
- 纯秒值,例如
6. 算法选择
当前阶段固定采用:
alg = HS256
理由:
- 与当前 Node 基线兼容,迁移阻力最低。
- 先把 claims、配置口径和 Bearer 主链稳定下来。
- 若未来升级到非对称签名,应作为独立任务处理,而不是夹带进当前重写链路。
7. Rust 结构设计
7.1 AccessTokenClaimsInput
用途:
- 作为业务层输入。
- 不承载
iat/exp/iss这种平台计算字段。
字段:
user_idsession_idproviderrolestoken_versionphone_verifiedbinding_statusdisplay_name
7.2 AccessTokenClaims
用途:
- 对应最终 JWT payload。
- 直接用于签名与验签结果输出。
字段:
isssubsidproviderrolesverphone_verifiedbinding_statusdisplay_nameiatexp
8. 校验规则
8.1 签发前校验
issuer、secret不能为空。- TTL 必须大于
0。 sub不能为空。sid不能为空。roles不能为空数组。exp必须晚于iat。
8.2 验签时校验
- 算法必须是
HS256。 - 签名必须正确。
iss必须匹配当前配置。exp/iat/iss/sub必须存在。- 反序列化后的
sid/provider/roles/ver/phone_verified/binding_status必须完整。
当前阶段不做的校验:
ver与数据库最新 token version 比对。sid与refresh_session活跃状态比对。roles的细粒度授权判断。
9. api-server 最小接线
本阶段 api-server 接线规则如下:
AppConfig增加 JWT 相关配置。AppState在启动时构造唯一一份JwtConfig。require_bearer_auth中间件从请求头读取 Bearer token。- 验签成功后把 claims 以
AuthenticatedAccessToken写入 request extensions。 - 内部路由
/_internal/auth/claims用于返回当前已校验 claims,作为阶段验收与调试入口。
说明:
- 这个内部路由不是最终对外 contract。
- 它的存在是为了在
module-auth与正式/api/auth/me落地前,先把 Bearer 主链单独跑通。
10. 测试策略
当前阶段要求至少覆盖:
platform-auth的 JWT 签发与验签回环。- issuer 不匹配时拒绝。
- 空角色拒绝。
api-server在无 Bearer token 时返回401。api-server在合法 Bearer token 下返回 claims。
11. 完成定义
当以下条件满足时,本任务视为完成:
- Rust workspace 中存在真实可编译的
platform-authcrate。 api-server已能使用platform-auth校验 Bearer JWT。- 工作区测试与编译可通过。
- 任务清单已同步更新。
12. 后续衔接
下一阶段继续衔接:
- refresh cookie 读取与轮换。
module-auth会话真相与token_version在线校验。/api/auth/me、/api/auth/refresh等正式接口。- SpacetimeDB 对 Axum JWT 的身份透传验证。