---
title: 头像声明与交付
description: Sudomimus 如何通过 UserInfo 提供真实头像与生成头像，并按应用扇区隔离头像 URL。
editUrl: true
head: []
template: doc
sidebar:
  order: 3
  hidden: false
  attrs: {}
pagefind: true
draft: false
---

Sudomimus 有两条头像身份声明：`STATIC_AVATAR` 与 `ANIMATED_AVATAR`，和邮箱、名、姓并列。通用的策略与授权模型见[身份声明与共享](/zh-cn/concepts/identity-claims/)；本页只讲头像字段本身该如何使用。

头像声明被发出时，UserInfo 用 `picture` 承载静态头像，用 `picture_animated` 承载动态头像。Sudomimus 会把这些 URL 按账户与应用所在扇区隔离。

## 头像出现在哪里

| 位置 | 字段 | 何时出现 |
|---|---|---|
| Session `/userinfo` | `picture` | 当静态头像声明解析为真实值或占位值时出现。 |
| Session `/userinfo` | `picture_animated` | 当动态头像声明解析为真实值或占位值时出现；没有动画时回落为 `picture`。 |
| OIDC `/userinfo` | `picture` | 当授予了 `profile` scope，且静态头像声明解析为真实值或占位值时出现。 |
| OIDC `/userinfo` | `picture_animated` | 当授予了 `profile` scope，且动态头像声明解析为真实值或占位值时出现；没有动画时回落为 `picture`。 |
| 签发令牌的响应外层 | `claims.staticAvatar`、`claims.animatedAvatar` | 始终包含在 `claims` 块中，用来说明应用的策略与用户的授权状态。 |

这个 URL 可以直接作为图片源使用。不要解析它、从它推断身份，也不要把它当作稳定用户标识。应用的用户键是应用 access token payload 中的 `sub`，或 OIDC ID token 的标准 `sub`。

## 真实头像与占位头像

两条头像声明都使用和其他身份声明相同的策略枚举：

| 策略 | 头像行为 |
|---|---|
| `OFF` | 不发出对应头像字段。 |
| `OPTIONAL` | 只有在用户授权头像声明后，才发出用户的账户头像；否则省略。 |
| `REQUIRED` | 用户授权头像声明后，发出用户的账户头像。非交互式签发点不会签发缺少它的令牌，而是拒绝。 |
| `SYNTHETIC_ONLY` | 始终发出扇区占位头像。它从不请求或共享用户的账户头像。 |
| `SYNTHETIC_FALLBACK` | 用户授权时发出账户头像；否则发出扇区占位头像。它从不阻塞登录。 |

用户的账户头像是真实头像声明值。它可以是用户上传的图片，也可以是 Sudomimus 生成的账户级默认头像；无论哪种，它都是用户控制的账户级头像。应用默认会获得静态占位头像（`staticAvatar = SYNTHETIC_ONLY`），动态头像默认关闭（`animatedAvatar = OFF`）。

占位头像则不同：它按 `(account, sector)` 生成，并和扇区主体的占位身份一起存储。因此，同一扇区里的两个应用可能看到同一个用户的同一张占位头像；不同扇区里的应用会收到互不相关的占位身份。

## 静态与动态版本

账户头像有一个静态 URL 和一个动态 URL。普通个人资料 UI 建议优先使用静态版本。动态版本适合明确支持动效的产品，例如更丰富的资料卡、游戏或社交界面。

如果所选头像没有动画，私有 `picture_animated` claim 会回落到静态 URL。

## 按扇区隔离的交付 URL

即使声明解析到用户的账户头像，应用看到的值也是按扇区隔离的交付 URL。这一点对隐私很重要：

- 把 URL 当作不透明值处理；不要从中解析标识符。
- 同一个账户头像，在不同扇区会显示为不同的交付 URL。
- 用户轮换扇区主体时，Sudomimus 会同时更新该扇区的占位身份与头像 URL。
- 一条此前已授权的头像声明不再授权时，Sudomimus 会更新这个账户与扇区对应的真实头像 URL。

应用可以把当前头像 URL 存为展示资料。不要把它们用于登录、账户合并、风控、allow-list 或跨应用关联。

## 更新、撤销与缓存

声明授权由 UserInfo 实时读取。下一次 `/userinfo` 响应可能因为以下原因新增、移除或改变头像字段：

- 用户授权或撤销任一头像声明；
- 开发者修改应用的声明策略；
- 用户修改自己的账户头像；
- 用户轮换扇区主体；
- `SYNTHETIC_FALLBACK` 因授权变化而在真实头像与占位头像之间切换。

请把 `picture` 与 `picture_animated` 当作可替换的个人资料字段。收到新值时，更新你保存的展示头像；字段缺席时，根据你的产品规则使用自有默认头像，或清除之前导入的头像。

撤销会阻止后续签发继续共享真实头像，并更新 Sudomimus 发给该扇区的头像 URL。它无法追回应用已经下载的副本，也无法清除 Sudomimus 之外的缓存。

## OIDC 行为

OIDC `/userinfo` 会把静态头像映射为 `picture`，把动态头像映射为私有 `picture_animated` claim。这两个字段都同时受头像声明结果和 `profile` scope 控制：

```json
{
  "sub": "<sector subject>",
  "picture": "<sector-scoped static avatar URL>",
  "picture_animated": "<sector-scoped animated avatar URL>"
}
```

如果没有授予 `profile`，即便声明策略本来会发出头像，这两个字段也会缺席。如果策略发出的是占位头像，OIDC 中的头像 URL 也会按同样的扇区隔离规则生成。

## 接入检查清单

- 只有产品确实需要展示用户图片时，才请求头像声明。
- 稳定生成头像已经足够、且不需要真实资料时，用 `SYNTHETIC_ONLY`。
- 希望优先使用用户真实头像，但登录不能被阻塞时，用 `SYNTHETIC_FALLBACK`。
- 只有真实账户头像对产品至关重要、且客户端能处理声明把关恢复时，才用 `REQUIRED`。
- 普通个人资料 UI 使用静态字段；只有明确支持动效的界面才使用动态字段。
- 用 `subject` / `sub` 标识用户，永远不要用头像 URL。
- 处理头像字段缺席，或在两次令牌签发之间发生变化的情况。

## 相关阅读

- [头像上传](/zh-cn/user-generated-content/avatar-uploads/) —— 账户侧上传与处理流程。
- [头像审核生命周期](/zh-cn/user-generated-content/avatar-review-lifecycle/) —— 上传通过审核前，账户页和应用会看到什么。
- [身份声明与共享](/zh-cn/concepts/identity-claims/) —— 策略、授权与 `claims` 块模型。
- [令牌与验证](/zh-cn/concepts/tokens-and-verification/) —— 头像 URL 字段在 JWT 中的位置。
- [成对身份](/zh-cn/concepts/pairwise-identity/) —— 为什么存在扇区隔离标识符和占位身份。
- [原生声明与 Errand](/zh-cn/native/claims-and-errand/) —— 原生 direct-issue 如何处理 required 声明。