认证中心
← 全部文档与搜索
独立页面 ↗下载 Markdown下载 OpenAPI
本文目录 · 15 节

认证中心 · 登录与应用授权 API

契约版本:1.2.2 · OpenAPI 3.1.1

覆盖 OAuth/OIDC 发现、授权、令牌、用户信息、撤销,以及软件授权激活、即时域名或设备绑定、查询和扣减。并非全部后台 API。servers 使用当前网站根路径,生产必须 HTTPS。OAuth 返回原始 JSON;/api/v1 使用 code/message/data 信封。所有示例都是虚构数据。

服务地址

/

认证方式

clientBasic

机密客户端 client_id / client_secret;也支持表单 client_secret_post

{
  "type": "http",
  "scheme": "basic",
  "description": "机密客户端 client_id / client_secret;也支持表单 client_secret_post"
}

oauthAccess

Authorization: Bearer <access_token>;不可使用 id_token 或机器发布 token

{
  "type": "oauth2",
  "description": "Authorization: Bearer <access_token>;不可使用 id_token 或机器发布 token",
  "flows": {
    "authorizationCode": {
      "authorizationUrl": "/oauth/authorize",
      "tokenUrl": "/oauth/token",
      "refreshUrl": "/oauth/token",
      "scopes": {
        "openid": "稳定用户标识与 ID Token",
        "profile": "显示名称 name",
        "email": "邮箱与验证标志",
        "offline_access": "刷新令牌",
        "license:read": "查询本人应用授权",
        "license:consume": "扣减本人应用用量",
        "license:activate": "兑换激活码并管理本人在当前应用的即时授权绑定"
      }
    }
  }
}

applicationKey

创建应用时显示的 API Key;仅存服务端

{
  "type": "apiKey",
  "in": "header",
  "name": "X-API-Key",
  "description": "创建应用时显示的 API Key;仅存服务端"
}

GET /.well-known/openid-configuration

获取 OIDC 配置

issuer 与所有端点均使用部署的 APP_ORIGIN。客户端应优先使用发现文档。

操作 ID:discoverOIDC

认证:公开,无凭据

响应

HTTP 200

OIDC 配置

application/json

字段类型必需说明
issuerstring是
authorization_endpointstring是
token_endpointstring是
userinfo_endpointstring是
revocation_endpointstring是
jwks_uristring是
response_types_supportedarray条件 / 否
grant_types_supportedarray条件 / 否
subject_types_supportedarray条件 / 否
id_token_signing_alg_values_supportedarray条件 / 否
scopes_supportedarray条件 / 否
token_endpoint_auth_methods_supportedarray条件 / 否
code_challenge_methods_supportedarray条件 / 否
claims_supportedarray是
{
  "$ref": "#/components/schemas/Discovery"
}

GET /.well-known/jwks.json

获取 ID Token 验签公钥

操作 ID:getJWKS

认证:公开,无凭据

响应

HTTP 200

RSA 公钥集,无私钥

application/json

字段类型必需说明
keysarray是
{
  "type": "object",
  "required": [
    "keys"
  ],
  "properties": {
    "keys": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/JWK"
      }
    }
  }
}

GET /oauth/authorize

浏览器发起授权码登录

该端点先跳转本站授权页面,参数在后续授权请求中校验;最终回调包含 code/state/iss 或 error/state/iss。code 有效期 60 秒且只能使用一次。state 必须核对。默认要求所有客户端使用 PKCE S256;申请 openid 必须提供 nonce。兼容例外见登录指南。

操作 ID:authorize

认证:公开,无凭据

参数

名称位置必需说明与约束
response_typequery是{"type":"string","enum":["code"]}
client_idquery是应用的公开 Client ID,不是应用 UUID {"type":"string"}
redirect_uriquery是与登记值精确一致,含路径编码 {"type":"string","format":"uri"}
scopequery是空格分隔,必须在应用允许的范围内 {"type":"string","example":"openid profile email"}
statequery是每次授权生成不可预测的随机值 {"type":"string","minLength":16,"maxLength":1024}
noncequery条件 / 否请求 openid 时必需;核对 ID Token nonce。仅显式启用兼容的机密客户端可省略 {"type":"string","minLength":16,"maxLength":512}
code_challengequery条件 / 否默认必需:BASE64URL(SHA256(code_verifier)),无填充;仅显式启用传统 OIDC 兼容的机密客户端可省略 {"type":"string"}
code_challenge_methodquery条件 / 否提供 challenge 时必需 {"type":"string","enum":["S256"]}
promptquery条件 / 否none 可能回调 login_required 或 consent_required;login 重新验证密码 {"type":"string","enum":["none","consent","login"]}

响应

HTTP 302

跳转本站授权页

响应头:

{
  "Location": {
    "schema": {
      "type": "string"
    },
    "description": "本站 /authorize 与原始查询参数"
  }
}

POST /oauth/token

交换授权码或刷新令牌

机密客户端使用 HTTP Basic(用户名 client_id、密码 client_secret)或表单认证;公开客户端只传 client_id。表单认证对应下列空 security 选项,仍须服务端校验。不要发送 JSON。刷新会轮换令牌,旧刷新令牌重放会撤销整个令牌族。access_token 为不透明字符串,不能当 JWT 解码。

操作 ID:exchangeToken

认证:clientBasic 或 公开客户端 / 表单认证,见接口说明

请求体(必需)

application/x-www-form-urlencoded

{
  "oneOf": [
    {
      "$ref": "#/components/schemas/CodeExchange"
    },
    {
      "$ref": "#/components/schemas/RefreshExchange"
    }
  ]
}

响应

HTTP 200

原始 JSON,无 data 包装

application/json

字段类型必需说明
access_tokenstring是不透明访问令牌;放入 Authorization: Bearer
token_typestring是
expires_ininteger是秒
scopestring是实际授权范围,空格分隔
refresh_tokenstring条件 / 否仅 offline_access 返回;受登录会话有效期限制,轮换后原子替换旧值
id_tokenstring条件 / 否仅 openid 返回,RS256 JWT 字符串;声明结构见 IDTokenClaims
{
  "$ref": "#/components/schemas/TokenResponse"
}

示例:

{
  "access_token": "example-access-token",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email",
  "id_token": "example.header.signature"
}

HTTP 400

invalid_grant(含过期、重放、PKCE/回调不符)、unsupported_grant_type 或其他授权校验失败

application/json

字段类型必需说明
errorstring是OAuth 错误码
{
  "$ref": "#/components/schemas/OAuthError"
}

示例:

{
  "error": "invalid_grant"
}

HTTP 401

invalid_client:客户端不存在、禁用或凭据错误

application/json

字段类型必需说明
errorstring是OAuth 错误码
{
  "$ref": "#/components/schemas/OAuthError"
}

HTTP 429

按 IP 限流,稍后重试;平台错误结构,不含 data

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

示例:

{
  "code": 42900,
  "message": "操作过于频繁,请稍后再试"
}

HTTP 503

OAuth 处理器返回 error;Redis 限流中间件返回 code/message。两种结构都须处理

application/json

{
  "oneOf": [
    {
      "$ref": "#/components/schemas/OAuthError"
    },
    {
      "$ref": "#/components/schemas/PlatformError"
    }
  ]
}

GET /oauth/userinfo

查询用户信息 · 字段映射

使用 OAuth access_token,必须含 openid;始终返回 application_creator 布尔值,表示当前用户是否为当前应用的创建人。profile 返回 name,email 返回 email/email_verified。所有字段位于根对象。当前不返回 picture、avatar、nickname、id、username、preferred_username、roles、phone_number。请验证响应 sub 与已经验签的 ID Token sub 一致。

操作 ID:getUserInfo

认证:oauthAccess(openid)

响应

HTTP 200

根据 token 实际 scope 返回用户声明;没有申请的字段会缺省

application/json

字段类型必需说明
substring是稳定的用户 UUID;用户唯一标识映射填 sub,JSONPath 填 $.sub。跨 issuer 使用 iss + sub 关联;scope: openid
application_creatorboolean是当前登录用户是否为当前 OAuth 应用的创建人。由服务端按 access_token 绑定的 application_id 与不可由用户提交的 owner_id 比较;可作为该应用的初始管理员依据,不代表认证中心平台管理员或其他应用权限;scope: openid
namestring条件 / 否平台昵称,可变且不保证唯一;映射填 name / $.name;scope: profile
emailstring条件 / 否邮箱;映射填 email / $.email,不用作稳定用户 ID;scope: email
email_verifiedboolean条件 / 否真实布尔值,可为 false;不要将未验证邮箱视为已验证身份;scope: email
{
  "$ref": "#/components/schemas/UserInfo"
}

仅 openid

{
  "sub": "00000000-0000-4000-8000-000000000001",
  "application_creator": false
}

openid profile email

{
  "sub": "00000000-0000-4000-8000-000000000001",
  "name": "示例用户",
  "email": "person@example.test",
  "email_verified": false,
  "application_creator": true
}

HTTP 401

invalid_token:访问令牌失效、被撤销、会话失效或账号/应用停用

application/json

字段类型必需说明
errorstring是OAuth 错误码
{
  "$ref": "#/components/schemas/OAuthError"
}

示例:

{
  "error": "invalid_token"
}

HTTP 403

insufficient_scope:缺少 openid

application/json

字段类型必需说明
errorstring是OAuth 错误码
{
  "$ref": "#/components/schemas/OAuthError"
}

示例:

{
  "error": "insufficient_scope"
}

POST /oauth/revoke

撤销访问/刷新令牌所属令牌族

与 token 端点使用相同客户端认证。未知或已撤销的 token 仍返回 200 空正文;不会退出认证中心全部浏览器会话。token_type_hint 当前不参与处理。

操作 ID:revokeToken

认证:clientBasic 或 公开客户端 / 表单认证,见接口说明

请求体(必需)

application/x-www-form-urlencoded

字段类型必需说明
tokenstring是待撤销的访问或刷新令牌
client_idstring条件 / 否未用 Basic 时必需
client_secretstring条件 / 否未用 Basic 的机密客户端必需
{
  "type": "object",
  "required": [
    "token"
  ],
  "properties": {
    "token": {
      "type": "string",
      "description": "待撤销的访问或刷新令牌"
    },
    "client_id": {
      "type": "string",
      "description": "未用 Basic 时必需"
    },
    "client_secret": {
      "type": "string",
      "description": "未用 Basic 的机密客户端必需"
    }
  }
}

响应

HTTP 200

成功,空正文

HTTP 401

invalid_client

application/json

字段类型必需说明
errorstring是OAuth 错误码
{
  "$ref": "#/components/schemas/OAuthError"
}

HTTP 429

按 IP 限流,稍后重试;平台错误结构,不含 data

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

示例:

{
  "code": 42900,
  "message": "操作过于频繁,请稍后再试"
}

HTTP 503

OAuth 处理器返回 error;Redis 限流中间件返回 code/message。两种结构都须处理

application/json

{
  "oneOf": [
    {
      "$ref": "#/components/schemas/OAuthError"
    },
    {
      "$ref": "#/components/schemas/PlatformError"
    }
  ]
}

POST /api/v1/auth/check

查询应用授权是否可用

API Key 只用于服务端、限制所属应用且应用须允许 license:read;OAuth token 还限制本人授权。不需要浏览器 Cookie/CSRF。HTTP 200 不表示授权有效,必须判断 data.valid。

操作 ID:checkLicense

认证:applicationKey 或 oauthAccess(license:read)

请求体(必需)

application/json

字段类型必需说明
authorization_idstring是具体软件授权 ID,不是应用 ID 或 client_id
binding_valuestring条件 / 否域名/设备型授权须传已验证绑定;其他类型可省略
{
  "$ref": "#/components/schemas/LicenseInput"
}

示例:

{
  "authorization_id": "00000000-0000-4000-8000-000000000002",
  "binding_value": "example.test"
}

响应

HTTP 200

授权结果;not_found 时只含 valid/reason

application/json

字段类型必需说明
codeobject是
messagestring是
dataobject是
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "const": 0
    },
    "message": {
      "type": "string"
    },
    "data": {
      "$ref": "#/components/schemas/LicenseCheck"
    }
  }
}

示例:

{
  "code": 0,
  "message": "success",
  "data": {
    "valid": false,
    "reason": "not_found"
  }
}

HTTP 400

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 403

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 429

按 IP 限流,稍后重试;平台错误结构,不含 data

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

示例:

{
  "code": 42900,
  "message": "操作过于频繁,请稍后再试"
}

HTTP 503

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

POST /api/v1/auth/consume

按幂等键扣减用量

应用须允许 license:consume;OAuth 同时限制用户。幂等范围为 authorization_id + idempotency_key,同键同数量重试返回当前 used,同键不同数量返回 409。仅支持 metered 授权。

操作 ID:consumeLicense

认证:applicationKey 或 oauthAccess(license:consume)

请求体(必需)

application/json

{
  "allOf": [
    {
      "$ref": "#/components/schemas/LicenseInput"
    },
    {
      "type": "object",
      "required": [
        "quantity",
        "idempotency_key"
      ],
      "properties": {
        "quantity": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000000000
        },
        "idempotency_key": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128
        }
      }
    }
  ]
}

示例:

{
  "authorization_id": "00000000-0000-4000-8000-000000000002",
  "quantity": 1,
  "idempotency_key": "example-order-001"
}

响应

HTTP 200

累计用量,不是剩余额度

application/json

字段类型必需说明
codeobject是
messagestring是
dataobject是
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "const": 0
    },
    "message": {
      "type": "string"
    },
    "data": {
      "type": "object",
      "required": [
        "used"
      ],
      "properties": {
        "used": {
          "type": "integer",
          "format": "int64"
        }
      }
    }
  }
}

示例:

{
  "code": 0,
  "message": "success",
  "data": {
    "used": 1
  }
}

HTTP 400

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 403

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 404

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 409

授权不可用、额度不足、非按量授权或同键不同数量

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 429

按 IP 限流,稍后重试;平台错误结构,不含 data

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

示例:

{
  "code": 42900,
  "message": "操作过于频繁,请稍后再试"
}

HTTP 503

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

POST /api/v1/authorizations/activate

为当前 OAuth 用户兑换软件授权激活码

仅接受用户 OAuth Access Token,不接受应用 API Key。认证中心从令牌确定用户和应用,并拒绝不属于该应用的激活码。浏览器工作台也使用同一路径,但采用站内会话与 CSRF。

操作 ID:activateAuthorization

认证:oauthAccess(license:activate)

请求体(必需)

application/json

字段类型必需说明
codestring是软件授权激活码;与通用码券不同
{
  "$ref": "#/components/schemas/ActivationRequest"
}

示例:

{
  "code": "AC-example-code"
}

响应

HTTP 200

已创建并归属当前用户的授权

application/json

字段类型必需说明
codeobject是
messagestring是
dataobject是
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "const": 0
    },
    "message": {
      "type": "string"
    },
    "data": {
      "$ref": "#/components/schemas/ActivationResult"
    }
  }
}

示例:

{
  "code": 0,
  "message": "success",
  "data": {
    "authorization_id": "00000000-0000-4000-8000-000000000002",
    "license_key": "00000000-0000-4000-8000-000000000002",
    "application_id": "00000000-0000-4000-8000-000000000003",
    "auth_type": "domain",
    "binding_limit": 1,
    "subdomain_limit": 5,
    "quota": 0
  }
}

HTTP 400

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 401

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 403

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 404

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 409

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 503

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

POST /api/v1/authorizations/{id}/bindings

为当前用户的软件授权添加设备或域名绑定

令牌用户和令牌应用必须同时与目标授权匹配。设备、根域名以及根域名下明确配置的子域名在绑定成功后立即生效,不需要 DNS 验证。

操作 ID:addAuthorizationBinding

认证:oauthAccess(license:activate)

参数

名称位置必需说明与约束
idpath是activate 返回的 authorization_id {"type":"string","format":"uuid"}

请求体(必需)

application/json

字段类型必需说明
binding_typestring是
binding_valuestring是域名不含协议、端口或路径;设备值由应用生成并保持稳定
parent_binding_idstring条件 / 否添加子域名时填写所属根域名的绑定 ID
{
  "$ref": "#/components/schemas/BindingRequest"
}

示例:

{
  "binding_type": "domain",
  "binding_value": "example.test"
}

响应

HTTP 200

绑定已创建

application/json

字段类型必需说明
codeobject是
messagestring是
dataobject是
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "const": 0
    },
    "message": {
      "type": "string"
    },
    "data": {
      "$ref": "#/components/schemas/BindingResult"
    }
  }
}

HTTP 400

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 401

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 403

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 404

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 409

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 503

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

POST /api/v1/authorizations/{id}/bindings/{binding}/verify

兼容旧客户端确认域名绑定

兼容旧客户端保留的入口。确认目标属于当前用户和当前应用后立即将旧绑定设为有效,不查询 DNS;新客户端无需调用。

操作 ID:confirmLegacyAuthorizationDomainBinding

认证:oauthAccess(license:activate)

参数

名称位置必需说明与约束
idpath是activate 返回的 authorization_id {"type":"string","format":"uuid"}
bindingpath是创建绑定返回的绑定 ID {"type":"string","format":"uuid"}

响应

HTTP 200

旧域名绑定已确认生效

application/json

字段类型必需说明
codeobject是
messagestring是
dataobject是
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "const": 0
    },
    "message": {
      "type": "string"
    },
    "data": {
      "type": "object",
      "required": [
        "verified"
      ],
      "properties": {
        "verified": {
          "const": true
        }
      }
    }
  }
}

HTTP 400

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 401

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 403

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 404

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 409

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 503

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

DELETE /api/v1/authorizations/{id}/bindings/{binding}

解绑设备或域名

受应用解绑冷却时间限制;移除根域名会级联移除其子域名。

操作 ID:removeAuthorizationBinding

认证:oauthAccess(license:activate)

参数

名称位置必需说明与约束
idpath是activate 返回的 authorization_id {"type":"string","format":"uuid"}
bindingpath是创建绑定返回的绑定 ID {"type":"string","format":"uuid"}

响应

HTTP 200

解绑成功

application/json

字段类型必需说明
codeobject是
messagestring是
datanull是
{
  "type": "object",
  "required": [
    "code",
    "message",
    "data"
  ],
  "properties": {
    "code": {
      "const": 0
    },
    "message": {
      "type": "string"
    },
    "data": {
      "type": "null"
    }
  }
}

HTTP 400

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 401

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 403

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 404

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 409

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

HTTP 503

400 输入错误;403 凭据/范围不符;404 授权不存在;503 服务不可用。错误 code 为 HTTP 状态 × 100

application/json

字段类型必需说明
codeinteger是
messagestring是
{
  "$ref": "#/components/schemas/PlatformError"
}

数据结构字典

上文的 $ref 指向以下命名结构。条件字段以说明中的 scope 和流程为准。

UserInfo

字段类型必需说明
substring是稳定的用户 UUID;用户唯一标识映射填 sub,JSONPath 填 $.sub。跨 issuer 使用 iss + sub 关联;scope: openid
application_creatorboolean是当前登录用户是否为当前 OAuth 应用的创建人。由服务端按 access_token 绑定的 application_id 与不可由用户提交的 owner_id 比较;可作为该应用的初始管理员依据,不代表认证中心平台管理员或其他应用权限;scope: openid
namestring条件 / 否平台昵称,可变且不保证唯一;映射填 name / $.name;scope: profile
emailstring条件 / 否邮箱;映射填 email / $.email,不用作稳定用户 ID;scope: email
email_verifiedboolean条件 / 否真实布尔值,可为 false;不要将未验证邮箱视为已验证身份;scope: email

完整结构与约束:

{
  "type": "object",
  "required": [
    "sub",
    "application_creator"
  ],
  "additionalProperties": false,
  "properties": {
    "sub": {
      "type": "string",
      "format": "uuid",
      "description": "稳定的用户 UUID;用户唯一标识映射填 sub,JSONPath 填 $.sub。跨 issuer 使用 iss + sub 关联",
      "x-scope": "openid",
      "x-mapping": "用户唯一标识"
    },
    "application_creator": {
      "type": "boolean",
      "description": "当前登录用户是否为当前 OAuth 应用的创建人。由服务端按 access_token 绑定的 application_id 与不可由用户提交的 owner_id 比较;可作为该应用的初始管理员依据,不代表认证中心平台管理员或其他应用权限",
      "x-scope": "openid",
      "x-mapping": "当前应用创建人"
    },
    "name": {
      "type": "string",
      "description": "平台昵称,可变且不保证唯一;映射填 name / $.name",
      "x-scope": "profile",
      "x-mapping": "显示名称 / 昵称"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "邮箱;映射填 email / $.email,不用作稳定用户 ID",
      "x-scope": "email",
      "x-mapping": "邮箱"
    },
    "email_verified": {
      "type": "boolean",
      "description": "真实布尔值,可为 false;不要将未验证邮箱视为已验证身份",
      "x-scope": "email",
      "x-mapping": "邮箱已验证"
    }
  }
}

IDTokenClaims

这是对解码后的声明结构的说明,不是 token 接口中的嵌套 JSON。必须通过 JWKS 验签,并验证 iss/aud/exp/nonce、UserInfo sub 一致性。刷新响应通常没有 nonce,不要将它作为新登录。

字段类型必需说明
issstring是APP_ORIGIN
substring是
audstring是client_id
iatinteger是签发时间,Unix 秒
expinteger是过期时间,Unix 秒,签发后 900 秒
noncestring条件 / 否授权码请求中提供时返回;刷新时省略
at_hashstring是access_token SHA256 左半段的 Base64URL
application_creatorboolean是当前登录用户是否为 aud 所指应用的创建人;仅在验签并校验 iss、aud、exp、nonce 后用于该应用内的管理员判定,不代表平台管理员权限
namestring条件 / 否profile scope
emailstring条件 / 否email scope
email_verifiedboolean条件 / 否email scope

完整结构与约束:

{
  "type": "object",
  "description": "这是对解码后的声明结构的说明,不是 token 接口中的嵌套 JSON。必须通过 JWKS 验签,并验证 iss/aud/exp/nonce、UserInfo sub 一致性。刷新响应通常没有 nonce,不要将它作为新登录。",
  "required": [
    "iss",
    "sub",
    "aud",
    "iat",
    "exp",
    "at_hash",
    "application_creator"
  ],
  "properties": {
    "iss": {
      "type": "string",
      "format": "uri",
      "description": "APP_ORIGIN"
    },
    "sub": {
      "type": "string",
      "format": "uuid"
    },
    "aud": {
      "type": "string",
      "description": "client_id"
    },
    "iat": {
      "type": "integer",
      "description": "签发时间,Unix 秒"
    },
    "exp": {
      "type": "integer",
      "description": "过期时间,Unix 秒,签发后 900 秒"
    },
    "nonce": {
      "type": "string",
      "description": "授权码请求中提供时返回;刷新时省略"
    },
    "at_hash": {
      "type": "string",
      "description": "access_token SHA256 左半段的 Base64URL"
    },
    "application_creator": {
      "type": "boolean",
      "description": "当前登录用户是否为 aud 所指应用的创建人;仅在验签并校验 iss、aud、exp、nonce 后用于该应用内的管理员判定,不代表平台管理员权限"
    },
    "name": {
      "type": "string",
      "description": "profile scope"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "email scope"
    },
    "email_verified": {
      "type": "boolean",
      "description": "email scope"
    }
  }
}

TokenResponse

字段类型必需说明
access_tokenstring是不透明访问令牌;放入 Authorization: Bearer
token_typestring是
expires_ininteger是秒
scopestring是实际授权范围,空格分隔
refresh_tokenstring条件 / 否仅 offline_access 返回;受登录会话有效期限制,轮换后原子替换旧值
id_tokenstring条件 / 否仅 openid 返回,RS256 JWT 字符串;声明结构见 IDTokenClaims

完整结构与约束:

{
  "type": "object",
  "required": [
    "access_token",
    "token_type",
    "expires_in",
    "scope"
  ],
  "properties": {
    "access_token": {
      "type": "string",
      "description": "不透明访问令牌;放入 Authorization: Bearer"
    },
    "token_type": {
      "type": "string",
      "enum": [
        "Bearer"
      ]
    },
    "expires_in": {
      "type": "integer",
      "const": 900,
      "description": "秒"
    },
    "scope": {
      "type": "string",
      "description": "实际授权范围,空格分隔"
    },
    "refresh_token": {
      "type": "string",
      "description": "仅 offline_access 返回;受登录会话有效期限制,轮换后原子替换旧值"
    },
    "id_token": {
      "type": "string",
      "description": "仅 openid 返回,RS256 JWT 字符串;声明结构见 IDTokenClaims"
    }
  }
}

CodeExchange

字段类型必需说明
grant_typestring是
codestring是回调中的一次性授权码
redirect_uristring是与发起授权的值完全一致
code_verifierstring条件 / 否默认必需,原始 PKCE verifier;仅未提交 challenge 且显式启用传统 OIDC 兼容的机密客户端可省略
client_idstring条件 / 否未用 Basic 时必需
client_secretstring条件 / 否未用 Basic 的机密客户端必需;公开客户端不携带

完整结构与约束:

{
  "type": "object",
  "required": [
    "grant_type",
    "code",
    "redirect_uri"
  ],
  "properties": {
    "grant_type": {
      "const": "authorization_code",
      "type": "string"
    },
    "code": {
      "type": "string",
      "description": "回调中的一次性授权码"
    },
    "redirect_uri": {
      "type": "string",
      "format": "uri",
      "description": "与发起授权的值完全一致"
    },
    "code_verifier": {
      "type": "string",
      "minLength": 43,
      "maxLength": 128,
      "description": "默认必需,原始 PKCE verifier;仅未提交 challenge 且显式启用传统 OIDC 兼容的机密客户端可省略"
    },
    "client_id": {
      "type": "string",
      "description": "未用 Basic 时必需"
    },
    "client_secret": {
      "type": "string",
      "description": "未用 Basic 的机密客户端必需;公开客户端不携带"
    }
  }
}

RefreshExchange

字段类型必需说明
grant_typestring是
refresh_tokenstring是上次返回的最新刷新令牌,不可并发复用
client_idstring条件 / 否未用 Basic 时必需
client_secretstring条件 / 否未用 Basic 的机密客户端必需

完整结构与约束:

{
  "type": "object",
  "required": [
    "grant_type",
    "refresh_token"
  ],
  "properties": {
    "grant_type": {
      "type": "string",
      "const": "refresh_token"
    },
    "refresh_token": {
      "type": "string",
      "description": "上次返回的最新刷新令牌,不可并发复用"
    },
    "client_id": {
      "type": "string",
      "description": "未用 Basic 时必需"
    },
    "client_secret": {
      "type": "string",
      "description": "未用 Basic 的机密客户端必需"
    }
  }
}

OAuthError

字段类型必需说明
errorstring是OAuth 错误码

完整结构与约束:

{
  "type": "object",
  "required": [
    "error"
  ],
  "properties": {
    "error": {
      "type": "string",
      "description": "OAuth 错误码"
    }
  }
}

PlatformError

字段类型必需说明
codeinteger是
messagestring是

完整结构与约束:

{
  "type": "object",
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  }
}

LicenseInput

字段类型必需说明
authorization_idstring是具体软件授权 ID,不是应用 ID 或 client_id
binding_valuestring条件 / 否域名/设备型授权须传已验证绑定;其他类型可省略

完整结构与约束:

{
  "type": "object",
  "required": [
    "authorization_id"
  ],
  "properties": {
    "authorization_id": {
      "type": "string",
      "format": "uuid",
      "description": "具体软件授权 ID,不是应用 ID 或 client_id"
    },
    "binding_value": {
      "type": "string",
      "description": "域名/设备型授权须传已验证绑定;其他类型可省略"
    }
  }
}

LicenseCheck

字段类型必需说明
validboolean是
reasonstring是空字符串表示有效;not_found 也可能表示当前凭据不可见该授权
expires_atstring,null条件 / 否null 表示没有到期时间;not_found 时省略
quotainteger条件 / 否总额度;not_found 时省略
usedinteger条件 / 否已用额度;not_found 时省略
auth_typestring条件 / 否授权类型;not_found 时省略

完整结构与约束:

{
  "type": "object",
  "required": [
    "valid",
    "reason"
  ],
  "properties": {
    "valid": {
      "type": "boolean"
    },
    "reason": {
      "type": "string",
      "enum": [
        "",
        "not_found",
        "expired_or_cancelled",
        "binding_not_verified",
        "quota_exhausted"
      ],
      "description": "空字符串表示有效;not_found 也可能表示当前凭据不可见该授权"
    },
    "expires_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "null 表示没有到期时间;not_found 时省略"
    },
    "quota": {
      "type": "integer",
      "format": "int64",
      "description": "总额度;not_found 时省略"
    },
    "used": {
      "type": "integer",
      "format": "int64",
      "description": "已用额度;not_found 时省略"
    },
    "auth_type": {
      "type": "string",
      "description": "授权类型;not_found 时省略"
    }
  }
}

JWK

字段类型必需说明
ktystring是
usestring是
algstring是
kidstring是当前 primary;按 token kid 选公钥
nstring是RSA modulus,Base64URL
estring是RSA exponent,Base64URL

完整结构与约束:

{
  "type": "object",
  "required": [
    "kty",
    "use",
    "alg",
    "kid",
    "n",
    "e"
  ],
  "properties": {
    "kty": {
      "type": "string",
      "enum": [
        "RSA"
      ]
    },
    "use": {
      "type": "string",
      "enum": [
        "sig"
      ]
    },
    "alg": {
      "type": "string",
      "enum": [
        "RS256"
      ]
    },
    "kid": {
      "type": "string",
      "description": "当前 primary;按 token kid 选公钥"
    },
    "n": {
      "type": "string",
      "description": "RSA modulus,Base64URL"
    },
    "e": {
      "type": "string",
      "description": "RSA exponent,Base64URL"
    }
  }
}

Discovery

字段类型必需说明
issuerstring是
authorization_endpointstring是
token_endpointstring是
userinfo_endpointstring是
revocation_endpointstring是
jwks_uristring是
response_types_supportedarray条件 / 否
grant_types_supportedarray条件 / 否
subject_types_supportedarray条件 / 否
id_token_signing_alg_values_supportedarray条件 / 否
scopes_supportedarray条件 / 否
token_endpoint_auth_methods_supportedarray条件 / 否
code_challenge_methods_supportedarray条件 / 否
claims_supportedarray是

完整结构与约束:

{
  "type": "object",
  "required": [
    "issuer",
    "authorization_endpoint",
    "token_endpoint",
    "userinfo_endpoint",
    "revocation_endpoint",
    "jwks_uri",
    "claims_supported"
  ],
  "properties": {
    "issuer": {
      "type": "string",
      "format": "uri"
    },
    "authorization_endpoint": {
      "type": "string",
      "format": "uri"
    },
    "token_endpoint": {
      "type": "string",
      "format": "uri"
    },
    "userinfo_endpoint": {
      "type": "string",
      "format": "uri"
    },
    "revocation_endpoint": {
      "type": "string",
      "format": "uri"
    },
    "jwks_uri": {
      "type": "string",
      "format": "uri"
    },
    "response_types_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "grant_types_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "subject_types_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "id_token_signing_alg_values_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "scopes_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "token_endpoint_auth_methods_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "code_challenge_methods_supported": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "claims_supported": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "sub",
          "name",
          "email",
          "email_verified",
          "application_creator"
        ]
      }
    }
  }
}

ActivationRequest

字段类型必需说明
codestring是软件授权激活码;与通用码券不同

完整结构与约束:

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "软件授权激活码;与通用码券不同"
    }
  }
}

ActivationResult

字段类型必需说明
authorization_idstring是兼容字段,与 license_key 相同
license_keystring是接入应用保存并用于后续授权校验的许可证密钥
application_idstring是
auth_typestring是
binding_limitinteger是
subdomain_limitinteger是
quotainteger是

完整结构与约束:

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "authorization_id",
    "license_key",
    "application_id",
    "auth_type",
    "binding_limit",
    "subdomain_limit",
    "quota"
  ],
  "properties": {
    "authorization_id": {
      "type": "string",
      "format": "uuid",
      "description": "兼容字段,与 license_key 相同"
    },
    "license_key": {
      "type": "string",
      "format": "uuid",
      "description": "接入应用保存并用于后续授权校验的许可证密钥"
    },
    "application_id": {
      "type": "string",
      "format": "uuid"
    },
    "auth_type": {
      "type": "string",
      "enum": [
        "membership",
        "subscription",
        "domain",
        "device",
        "metered"
      ]
    },
    "binding_limit": {
      "type": "integer",
      "minimum": 0
    },
    "subdomain_limit": {
      "type": "integer",
      "minimum": 0
    },
    "quota": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    }
  }
}

BindingRequest

字段类型必需说明
binding_typestring是
binding_valuestring是域名不含协议、端口或路径;设备值由应用生成并保持稳定
parent_binding_idstring条件 / 否添加子域名时填写所属根域名的绑定 ID

完整结构与约束:

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "binding_type",
    "binding_value"
  ],
  "properties": {
    "binding_type": {
      "type": "string",
      "enum": [
        "domain",
        "device"
      ]
    },
    "binding_value": {
      "type": "string",
      "maxLength": 255,
      "description": "域名不含协议、端口或路径;设备值由应用生成并保持稳定"
    },
    "parent_binding_id": {
      "type": "string",
      "format": "uuid",
      "description": "添加子域名时填写所属根域名的绑定 ID"
    }
  }
}

BindingResult

字段类型必需说明
idstring是
verifiedboolean是

完整结构与约束:

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "verified"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "verified": {
      "type": "boolean"
    }
  }
}