令牌与用户信息 开发人员

上次更新:2026年8月15日

令牌与用户信息

本文介绍如何在成功换取令牌后校验 ID Token、使用 Access Token,以及读取 UserInfo 返回的声明。

令牌类型

令牌形态(门户应用)用途
id_tokenJWT,ES256 签名向客户端证明用户已认证;内含 pairwise sub
access_tokenJWT,ES256 签名调用 UserInfo 等受保护资源;可用 JWKS 验签
refresh_token不透明令牌(仅机密客户端)刷新 Access Token

发现文档中的 id_token_signing_alg_values_supported 应包含 ES256。用于验签的公钥可从以下端点获取:

GET {ISSUER}/oauth2/jwks

建议缓存 JWKS,并根据 kid 选择密钥;发生密钥轮换时,请重新获取 JWKS。

ID Token 校验(必做)

至少校验:

  1. 签名:ES256 + JWKS。
  2. iss:等于你的 Issuer(如 https://api-passport.swaymoon.com)。
  3. aud:包含你的 client_id
  4. exp / iat:令牌未过期,并为时钟偏差保留合理的容差。
  5. nonce(若你在授权请求中发送了):与会话中保存的值一致。

ID Token 中的 sub 是面向你的应用(团队)的稳定用户标识。应用方应使用该字段作为关联本地用户的主键。

当前实现下,email 与多数资料类声明以 UserInfo 为准;请勿假设 ID Token 内一定含有 emailpicture。例外:已授予 locale 时,ID Token 会包含 locale(BCP 47,如 zh-CN / zh-TW / en / ja),授权回调即可读取用户首选语言。校验完 ID Token 的 sub 后,用 Access Token 调用 UserInfo 读取其余声明。

Pairwise sub

通行账户对已绑定开发者团队的客户端使用 pairwise 主体标识

  • 同一自然人用户多次登录你的团队下的应用时,sub 保持相同
  • 同一用户向另一团队的应用授权时,sub 不同
  • 因此,不要假设可以通过 sub 关联不同应用或团队中的用户,也不要使用邮箱替代 sub 作为唯一主键,因为用户可能更换绑定邮箱。

UserInfo

GET /userinfo
Host: api-passport.swaymoon.com
Authorization: Bearer ACCESS_TOKEN

该端点返回 JSON 格式的声明。其中,sub 与 ID Token 中的值一致(pairwise)。

始终包含

声明含义
subpairwise 用户标识(只要有 openid

资料声明:分项授权 + 默认值

下列声明始终出现在 UserInfo 响应中(字段形状稳定)。是否为真实用户数据,取决于令牌 scope 是否包含对应细项(见《权限与同意》)。

声明所需 scope已授权时未授权时(默认值)
namename展示名摇月用户
nicknamenickname昵称;未设置则为 摇月用户摇月用户
picturepicture头像 HTTPS URL;未设置则为空字符串""
biographybiography个性签名;未设置则为空字符串""
gendergendermale / female / other;未设置则为空字符串""
birthdatebirthdateYYYY-MM-DD;未设置则为空字符串""
regionregion地区代码;未设置则为空字符串""
preferred_usernamepreferred_username用户名;未设置则为空字符串""
localelocaleBCP 47 标签(zh-CN / zh-TW / en / ja""
updated_at任一资料细项资料更新时间(Unix 秒)0

不要把默认值当成用户真实资料。请结合令牌中的 scope 判断哪些字段已获授权;未出现在 scope 中的资料项仅为占位。

旧令牌若仍含整包 profile,服务端视为上述全部资料细项均已授权。

picture(头像)

已授予 picture 且用户已设置头像时,UserInfo 返回绝对 HTTPS URL(Issuer 域,例如 https://api-passport.swaymoon.com/media/avatars/…),可直接在浏览器或服务端拉取,无需额外鉴权。未设置头像时为空字符串。

接入方落库时可二选一(或按产品需要组合):

  1. 只存链接:把 picture URL 写入本地用户资料,展示时直接引用通行账户提供的地址。无需自建对象存储或图床;实现简单。注意:用户日后更换头像后,旧 URL 可能失效(文件名含随机段),宜在登录/刷新资料时更新本地保存的链接,或展示前再读一次 UserInfo。
  2. 存头像文件:用你方服务端(或安全的客户端)GET 该 HTTPS URL,下载图片后写入自有存储,本地只保留你方资源地址。适合希望图片长期由己方 CDN 托管、或需离线/裁剪处理的场景。请遵守合理缓存与体积限制,勿高频重复拉取。

两种方式都依赖生产环境 Issuer 为 HTTPS;本地联调若 Issuer 为 http://…,返回的也可能是 HTTP,上线前请按生产配置验证。

email

仅当令牌包含 email 时返回:

声明含义
email可用于联系该用户的邮箱地址(已验证)
email_verifiedtrue(在返回邮箱时)

未授予 email 时,响应中不会包含上述邮箱声明(与资料默认值策略不同)。

用户在同意页可以选择用普通邮箱隐私邮箱把邮箱权限授给你方:

用户选择你方收到的 email真实邮箱
普通邮箱用户账户绑定的邮箱即该地址
隐私邮箱专用于你方应用的中继地址(…@privaterelay.swaymoon.com不会通过 UserInfo 或其它 OAuth 通道提供给你方;发往该中继地址的邮件会由通行账户转发至用户真实邮箱

两种情况下,email 都是可正常收信的地址,请按普通邮箱处理(注册建档、发信、展示即可)。请了解用户可能选择隐私邮箱,因此不要假设该地址一定是用户的私人常用邮箱,也不要尝试索取或推断真实地址。账号主键请仍使用 sub

需要邮箱才能完成授权: 授权请求含 email,且用户勾选/必选授予该权限时,若账户尚未绑定邮箱,通行账户会先引导用户绑定并验证,成功后再继续同意与发码。因此令牌带有 email scope 时,UserInfo 应始终包含 emailemail_verified。用户也可取消可选的 email 后继续(若你方未将其设为必选)。

撤销与内省

  • 撤销:POST {ISSUER}/oauth2/revoke(按照 RFC 7009 和服务器实现传入令牌)。
  • 内省:POST {ISSUER}/oauth2/introspect(机密客户端可查询令牌状态)。

具体参数以发现文档与服务器响应为准。

建档建议

  1. 用校验后的 sub 查找或创建本地用户。
  2. 按令牌 scope 解释资料字段;将未授权字段的默认值视为「不可用」,不要写入业务档案。
  3. 头像:优先决定「只存 HTTPS 链接」还是「下载后自建存储」,见上文 picture
  4. 机密客户端须妥善保存 client_secret;非机密客户端无密钥。不要尝试收集或存储用户的通行账户密码。
  5. Access Token 的有效期较短,请按需刷新;用户退出登录时,可根据产品需要撤销 Refresh Token。

下一步:阅读《权限与同意》;如在接入过程中遇到问题,请参阅《示例与排错》。