跳到正文
MuoCeon 文档中心
第三方 OAuth 接入参考

令牌

访问令牌、刷新令牌与 id_token 的结构、claim 含义与校验步骤。

MuoCeon 签发三种令牌:访问令牌(access token)、刷新令牌(refresh token)、身份令牌(id_token)。访问令牌与 id_token 是签名 JWT,你可以本地验签;刷新令牌对客户端是不透明的,不要解析。

访问令牌

  • 算法:RS256,header 里 typ 为 at+jwt。
  • 验签公钥:{issuer}/jwks,按 header 的 kid 匹配。
  • 寿命:机密客户端 1 小时,公开客户端 30 分钟。
{
  "iss": "https://id.example.com/v1/oauth",
  "aud": ["auth", "https://id.example.com/v1/auth"],
  "client_id": "app_9f3c",
  "cid": "app_9f3c",
  "principal": "user",
  "sub": "0192f3a4-...",
  "scope": "openid profile email",
  "at_version": 1,
  "acr": "urn:muoceon:acr:aal2",
  "auth_time": 1760000000,
  "iat": 1760000000,
  "nbf": 1759999995,
  "exp": 1760003600,
  "jti": "..."
}
claim含义
iss授权服务器标识,必须与元数据里的 issuer 逐字一致
aud受众,同时含代号(auth)与资源标识符(https://…/v1/auth)
client_id / cid签发对象;两者取值相同,前者是标准字段
principaluser 表示代表用户,client 表示代表应用(client_credentials)
sub用户稳定标识,仅用户令牌存在
did设备标识,仅第一方客户端的令牌存在
scope本次实际生效的 scope(已按客户端能力裁剪)
at_version会话版本号,会话被撤销/封禁后递增,旧令牌即失效
acr / auth_time签发时刻的认证强度与认证时间,之后不再变化
authorization_details细粒度授权,仅当授权请求申请过才出现
jti / iat / nbf / exp标准令牌标识与时间窗

acr 与 auth_time 是快照

令牌一旦签发就不再变化:用户之后提权不会让旧令牌变强,刷新也不会让 auth_time 变新。 需要「刚刚认证过」的判断,必须基于新签发的令牌。

刷新令牌

  • 形态:签名 JWT,但对客户端是不透明的——内部结构与 jti 都不应被依赖。
  • 寿命:机密客户端 30 天,公开客户端 14 天,不因刷新而延长到超过上限。
  • 轮换:每次刷新都换新的,旧值立即失效;同一会话的旧访问令牌也会失效。

不要解析、不要拼接、不要假设长度。你只需要把它存好,刷新时原样提交。

id_token

仅在授权码换令牌、且 scope 含 openid 时签发。

{
  "iss": "https://id.example.com/v1/oauth",
  "sub": "0192f3a4-...",
  "aud": "app_9f3c",
  "exp": 1760003600,
  "iat": 1760000000,
  "at_hash": "...",
  "auth_time": 1760000000
}
  • aud 是你的 client_id,不是资源受众——这与访问令牌刻意不同。
  • 只携带协议 claim;昵称、邮箱等资料不在 id_token 里,走 UserInfo。
  • at_hash 可用于把 id_token 与本次拿到的访问令牌绑定。

校验步骤

按顺序做,任何一步失败即拒绝:

  1. 从 jwks_uri 取公钥,按 kid 验签(RS256)。
  2. 校验 iss 与可信 issuer 一致。
  3. 校验 aud 命中预期:访问令牌看资源标识符,id_token 看自己的 client_id。
  4. 校验 exp 未过、nbf 未到(留少量时钟偏移,例如 60 秒)。
  5. 需要身份资料时调 UserInfo,不要试图从访问令牌里读昵称或邮箱。

UserInfo 的受众是 auth

https://id.example.com/v1/auth/userinfo 要求令牌受众为 auth,且 scope 里至少有 openid / profile / email 之一。拿 oauth 受众的令牌调它一定失败。

撤销与内省

操作端点效果
撤销POST {issuer}/revoke撤销整个会话:该用户 + 该客户端(第一方还含该设备)的访问令牌与刷新令牌一并失效
内省POST {issuer}/introspect返回令牌是否有效及元信息;仅机密客户端可调用

撤销端点对不存在的令牌同样返回 200,不要用它判断令牌是否存在。撤销成功后你手上的访问令牌会立刻失效——包括你正准备用来调接口的那一枚。

令牌存哪里

令牌机密客户端公开客户端
访问令牌服务端内存/会话内存变量(不要写 localStorage)
刷新令牌服务端加密存储系统钥匙串 / 安全存储
id_token仅用于读取身份,可短期缓存同左

任何令牌都不要进日志、URL、Referer 可泄漏的位置。

本页目录