原生声明与 Errand
Steam ticket 与 AccessKey direct-issue 不经过应用自己的登录页面。这让成功路径非常短,但也意味着客户端无法展示同意界面,或要求用户当场补齐个人资料。
本页同时处理这个限制的两面:
- 为非交互式客户端选择合适的声明策略。
- 当 required 真实声明无法签发时,处理 Errand 浏览器交接。
共享的策略与授权模型见身份声明与共享。
选择原生声明策略
Section titled “选择原生声明策略”| 策略 | 原生 direct-issue 行为 |
|---|---|
| Off | 从不请求。 |
| Optional | 仅在用户此前已经授权时共享。永不阻塞,因此纯原生用户可能永远不会被提示。 |
| Required | 保证使用真实数据且一定存在。缺少同意或数据时返回带 Errand 的 403。 |
| Synthetic | 保证存在;已授权时使用真实数据,否则使用稳定占位值。永不阻塞,也不会创建 Errand。 |
对大多数原生集成,除非你明确需要经过验证的真实数据,否则应优先选择 SYNTHETIC 而不是 REQUIRED。
- 只需要稳定的姓名或邮箱形态值,可以接受占位:使用
SYNTHETIC。 - 需要真实、已验证的邮箱用于送达或外部对账:使用
REQUIRED并实现 Errand 流程。 - 用户已经授权时希望拿到真实数据,但缺少时仍可继续:使用
OPTIONAL。
如果所有请求的声明都是 OFF 或 SYNTHETIC,声明策略就永远不会迫使 direct-issue 进入浏览器交接。
Synthetic 姓名是生成的占位值;Synthetic 邮箱使用稳定的 …@proxy.sudomimus.email 地址。代理投递仅为尽力而为,不保证送达;OIDC 会把 synthetic 邮箱标记为 email_verified: false。
Errand
Section titled “Errand”Errand 是短暂的账户补救流程,不负责签发令牌。当 direct-issue 无法满足 required 声明时,403 响应会向客户端提供一个浏览器 URL。用户在那里完成同意或补资料,随后客户端重试原来的 direct-issue。
只有两种声明把关原因会携带 Errand:
403 reason | 含义 | 浏览器内的工作 |
|---|---|---|
ClaimConsentRequired | required 声明尚未获得授权。 | 授予同意;必要时先补齐缺失数据。 |
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 }轮询不是强制的。客户端也可以让用户在浏览器完成后手动确认,再执行重试。
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。