跳转到内容

原生声明与 Errand

查看 Markdown

Steam ticket 与 AccessKey direct-issue 不经过应用自己的登录页面。这让成功路径非常短,但也意味着客户端无法展示同意界面,或要求用户当场补齐个人资料。

本页同时处理这个限制的两面:

  1. 为非交互式客户端选择合适的声明策略。
  2. 当 required 真实声明无法签发时,处理 Errand 浏览器交接。

共享的策略与授权模型见身份声明与共享

策略原生 direct-issue 行为
Off从不请求。
Optional仅在用户此前已经授权时共享。永不阻塞,因此纯原生用户可能永远不会被提示。
Required保证使用真实数据且一定存在。缺少同意或数据时返回带 Errand 的 403
Synthetic保证存在;已授权时使用真实数据,否则使用稳定占位值。永不阻塞,也不会创建 Errand。

对大多数原生集成,除非你明确需要经过验证的真实数据,否则应优先选择 SYNTHETIC 而不是 REQUIRED

  • 只需要稳定的姓名或邮箱形态值,可以接受占位:使用 SYNTHETIC
  • 需要真实、已验证的邮箱用于送达或外部对账:使用 REQUIRED 并实现 Errand 流程。
  • 用户已经授权时希望拿到真实数据,但缺少时仍可继续:使用 OPTIONAL

如果所有请求的声明都是 OFFSYNTHETIC,声明策略就永远不会迫使 direct-issue 进入浏览器交接。

Synthetic 姓名是生成的占位值;Synthetic 邮箱使用稳定的 …@proxy.sudomimus.email 地址。代理投递仅为尽力而为,不保证送达;OIDC 会把 synthetic 邮箱标记为 email_verified: false

Errand 是短暂的账户补救流程,不负责签发令牌。当 direct-issue 无法满足 required 声明时,403 响应会向客户端提供一个浏览器 URL。用户在那里完成同意或补资料,随后客户端重试原来的 direct-issue。

只有两种声明把关原因会携带 Errand:

403 reason含义浏览器内的工作
ClaimConsentRequiredrequired 声明尚未获得授权。授予同意;必要时先补齐缺失数据。
RequiredClaimDataMissing已有同意,但账户缺少真实值。注册邮箱或补全缺失姓名。

规则拒绝、账户禁用等其他 403 都是终态,不会包含 Errand。

{
"reason": "ClaimConsentRequired",
"claims": {
"email": { "requirement": "REQUIRED", "state": "UNKNOWN" },
"firstName": { "requirement": "OPTIONAL", "state": "UNKNOWN" },
"lastName": { "requirement": "OFF", "state": "UNKNOWN" }
},
"errand": {
"errandKey": "ernd_...",
"url": "https://via.sudomimus.com/errand?key=ernd_...",
"expiresAt": "2026-06-10T12:30:00Z"
}
}
  • 在用户的系统浏览器中打开 errand.url
  • errandKey 当作 bearer secret;轮询状态时也使用它。
  • Errand 只能使用一次,并在 30 分钟后过期。
原生客户端 ── direct-issue ──▶ 403 { reason, claims, errand }
├── 在系统浏览器中打开 errand.url
├── 轮询 GET /errand/{errandKey}/status
└── 收到 COMPLETED 后重试一次 direct-issue ──▶ 200 { tokens, claims }

轮询不是强制的。客户端也可以让用户在浏览器完成后手动确认,再执行重试。

Terminal window
curl https://native-api.sudomimus.com/errand/ernd_.../status
# → { "status": "PENDING" }
# → { "status": "COMPLETED" }
# → { "status": "EXPIRED" }

建议大约每两秒轮询一次,并设置合理的总超时。EXPIRED 会刻意覆盖未知、格式错误、已消费和真正过期的 key;收到后重新执行 direct-issue 获取新的交接。状态端点本身永远不会签发令牌。

只要现有 Errand 至少还剩 15 分钟,且待办事项没有变化,重试通常会返回同一个 Errand,避免激进的重试循环把用户进度拆到多个 URL。

  • 仅需同意:不要求额外登录,因为凭据持有者已经证明自己控制着一项可签发令牌的凭据。
  • 需要写入身份数据:浏览器会要求登录,且登录账户必须与 Steam ticket 或 AccessKey 解析出的账户一致。
  • Optional 与 Synthetic 声明永远不会创建 Errand。
  • Connect /refresh 与 OIDC /token 不会内嵌 Errand。原生会话在 refresh 时被阻塞,需要重新执行 direct-issue。