通行证与应用授权
GET /cm/passport/.well-known/openid-configuration
通行证与应用授权 · /passport/.well-known/openid-configuration
权限:路由未直接调用登录检查;委托处理器可能另行校验,见说明。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/.well-known/openid-configuration' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
platform | 'CurrentStation 通行证' |
protocol | 'OAuth 2.0 (authorization_code + PKCE)' |
version | '1.0' |
issuer | f'{base}/cm' |
endpoints | {'authorize': f'{pbase}/authorize', 'token': f'{pbase}/token', 'userinfo': f'{pbase}/userinfo', 'introspect': |
scopes | [{'scope': k, 'label': v['label'], 'desc': v['desc'], 'required': v['required']} for k, v in cm_passport.SCOPE |
scope_default | cm_passport.DEFAULT_SCOPE |
grant_types | list(cm_passport.GRANT_TYPES) |
code_challenge_methods | ['S256'] |
token_ttl | {'code': cm_passport.CODE_TTL, 'access': cm_passport.ACCESS_TTL, 'refresh': cm_passport.REFRESH_TTL} |
first_party_apps | [{'client_id': a['key'], 'name': a['name']} for a in apps if a['first_party']] |
accounts_endpoint | f'{base}/cm/auth/login' |
实现定位:backend/cm_server.py:2231。接口参数和返回条件均来自该路由分支。
GET /cm/passport/.well-known/userinfo
通行证与应用授权 · /passport/.well-known/userinfo
权限:路由未直接调用登录检查;委托处理器可能另行校验,见说明。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 403 | '账号不可用' |
| 403 | '这是应用令牌(client_credentials),没有用户信息' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/.well-known/userinfo' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
响应体 | out |
实现定位:backend/cm_server.py:2752。接口参数和返回条件均来自该路由分支。
POST /cm/passport/.well-known/userinfo
通行证与应用授权 · /passport/.well-known/userinfo
权限:路由未直接调用登录检查;委托处理器可能另行校验,见说明。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 403 | '账号不可用' |
| 403 | '这是应用令牌(client_credentials),没有用户信息' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/.well-known/userinfo' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
响应体 | out |
实现定位:backend/cm_server.py:2752。接口参数和返回条件均来自该路由分支。
GET /cm/passport/apps
创建或列出应用
权限:Bearer。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| query | all | 未在 get 中指定 |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/apps?all=<all>' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
apps | out |
quota | {'max': MAX_APPS_PER_USER, 'used': len([a for a in cm_db.passport_app_list() if a['owner_uid'] == u['id']]), 'admin': is_admin} |
实现定位:backend/cm_server.py:2464。接口参数和返回条件均来自该路由分支。
POST /cm/passport/apps
创建或列出应用
权限:Bearer。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 400 | '应用名称过长(最多 60 字)' |
| 400 | '请填写应用名称' |
| 400 | '请至少填写一个回调地址(redirect_uri)' |
| 429 | f'每个账号最多登记 {MAX_APPS_PER_USER} 个应用,如需更多请联系管理员' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/apps' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 201
| 字段 | 取值/生成逻辑 |
|---|---|
clientId | key |
clientSecret | secret |
name | name |
redirects | redirects |
scopes | scopes |
public | is_public |
note | 'clientSecret 只在创建时返回一次,请立即保存到服务端环境变量' if secret else '公开客户端:不需要密钥,必须使用 PKCE' |
实现定位:backend/cm_server.py:2429。接口参数和返回条件均来自该路由分支。
DELETE /cm/passport/apps/{client_id}
编辑、停用应用
权限:Bearer。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| path | client_id | 路径占位符;按业务替换 |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request DELETE 'https://music.20110208.xyz/cm/passport/apps/{client_id}' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
ok | True |
实现定位:backend/cm_server.py:2531。接口参数和返回条件均来自该路由分支。
PATCH /cm/passport/apps/{client_id}
通行证与应用授权 · /passport/apps/{client_id}
权限:CurrentMusic Bearer 登录态;房间/绑定等条件另见校验。
路由分支含 PATCH 别名,但当前 HTTP Handler 没有实现 do_PATCH;公网请使用同路径的 PUT,PATCH 不作为可用入口承诺。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| path | client_id | 路径占位符;按业务替换 |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 400 | '至少保留一个回调地址' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request PATCH 'https://music.20110208.xyz/cm/passport/apps/{client_id}' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
ok | True |
app | _app_json(cm_db.passport_app_get(app['key'])) |
实现定位:backend/cm_server.py:2486。接口参数和返回条件均来自该路由分支。
PUT /cm/passport/apps/{client_id}
编辑、停用应用
权限:Bearer。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| path | client_id | 路径占位符;按业务替换 |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 400 | '至少保留一个回调地址' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request PUT 'https://music.20110208.xyz/cm/passport/apps/{client_id}' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
ok | True |
app | _app_json(cm_db.passport_app_get(app['key'])) |
实现定位:backend/cm_server.py:2486。接口参数和返回条件均来自该路由分支。
POST /cm/passport/apps/{client_id}/secret
轮换应用密钥
权限:Bearer。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| path | client_id | 路径占位符;按业务替换 |
| JSON body | revokeGrants | 未在 get 中指定 |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/apps/{client_id}/secret' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"revokeGrants": "<revokeGrants>"}'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
clientId | app['key'] |
clientSecret | secret |
revokedGrants | revoked |
note | 'clientSecret 只返回这一次;旧密钥立即失效' |
实现定位:backend/cm_server.py:2541。接口参数和返回条件均来自该路由分支。
GET /cm/passport/authorize
授权同意页与批准
权限:用户会话。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/authorize'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
app | {'clientId': app['key'], 'name': app['name'], 'homepage': app['homepage'], 'logo': app['logo'],  |
redirectUri | redirect_uri |
scope | scope |
scopes | [{'scope': k, 'label': v['label'], 'desc': v['desc'], 'required': v['required'], 'requested': True, |
user | {'sub': sub, 'nickname': u.get('nickname') or '', 'avatar': u.get('avatar') or '', 'title': u.get(&# |
state | state |
ttl | {'code': cm_passport.CODE_TTL, 'access': cm_passport.ACCESS_TTL, 'refresh': cm_passport.REFRESH_TTL} |
实现定位:backend/cm_server.py:2575。接口参数和返回条件均来自该路由分支。
POST /cm/passport/authorize
授权同意页与批准
权限:用户会话。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/authorize'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
redirect | f'{redirect_uri}{sep}code={quote(code)}' + (f'&state={quote(state)}' if state else '') |
expiresIn | cm_passport.CODE_TTL |
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
redirect | f'{redirect_uri}{sep}error=access_denied' + (f'&state={quote(state)}' if state else '') |
实现定位:backend/cm_server.py:2599。接口参数和返回条件均来自该路由分支。
GET /cm/passport/docs
兼容入口,302 跳转至 /api-docs/reference/guide-passport-api/
权限:公开。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/docs'
返回类型
此分支使用专用处理器、文件或事件流响应,或在共享分支中组装 JSON。具体结构见对应专题;文件流不能按 JSON 解析。
实现定位:backend/cm_server.py:2425。接口参数和返回条件均来自该路由分支。
GET /cm/passport/events
通行证与应用授权 · /passport/events
权限:CurrentMusic Bearer 登录态;房间/绑定等条件另见校验。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| query | app_key | ''(空值时回退) |
| query | limit | 100(空值时回退) |
| query | uid | 0(空值时回退) |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 403 | '需要管理员权限' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/events?limit=<limit>&app_key=<app_key>&uid=<uid>' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
events | rows |
实现定位:backend/cm_server.py:2872。接口参数和返回条件均来自该路由分支。
GET /cm/passport/grants
已授权应用列表
权限:Bearer。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/grants' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
grants | out |
实现定位:backend/cm_server.py:2846。接口参数和返回条件均来自该路由分支。
DELETE /cm/passport/grants/{grant_id}
通行证与应用授权 · /passport/grants/{grant_id}
权限:CurrentMusic Bearer 登录态;房间/绑定等条件另见校验。
请求参数
| 位置 | 字段 | 默认/读取方式 |
|---|---|---|
| path | grant_id | 路径占位符;按业务替换 |
表格列出实际代码读取的字段;get 的默认值不等于业务可省略。必填、长度和取值约束见下方校验及关联专题。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 404 | '授权不存在或已撤销' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request DELETE 'https://music.20110208.xyz/cm/passport/grants/{grant_id}' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
ok | True |
revoked | n |
实现定位:backend/cm_server.py:2862。接口参数和返回条件均来自该路由分支。
POST /cm/passport/introspect
校验令牌
权限:客户端。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 401 | 'Basic 认证头解析失败' |
| 401 | '客户端认证失败' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/introspect'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
active | True |
scope | g['scope'] |
client_id | g['app_key'] |
token_type | kind |
exp | exp |
iat | g['created_at'] |
sub | cm_db.passport_uid(g['uid']) if g['uid'] else '' |
username | '' |
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
active | False |
实现定位:backend/cm_server.py:2776。接口参数和返回条件均来自该路由分支。
GET /cm/passport/meta
通行证元信息与发现文档
权限:公开。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/meta'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
platform | 'CurrentStation 通行证' |
protocol | 'OAuth 2.0 (authorization_code + PKCE)' |
version | '1.0' |
issuer | f'{base}/cm' |
endpoints | {'authorize': f'{pbase}/authorize', 'token': f'{pbase}/token', 'userinfo': f'{pbase}/userinfo', 'introspect': |
scopes | [{'scope': k, 'label': v['label'], 'desc': v['desc'], 'required': v['required']} for k, v in cm_passport.SCOPE |
scope_default | cm_passport.DEFAULT_SCOPE |
grant_types | list(cm_passport.GRANT_TYPES) |
code_challenge_methods | ['S256'] |
token_ttl | {'code': cm_passport.CODE_TTL, 'access': cm_passport.ACCESS_TTL, 'refresh': cm_passport.REFRESH_TTL} |
first_party_apps | [{'client_id': a['key'], 'name': a['name']} for a in apps if a['first_party']] |
accounts_endpoint | f'{base}/cm/auth/login' |
实现定位:backend/cm_server.py:2231。接口参数和返回条件均来自该路由分支。
POST /cm/passport/revoke
撤销令牌
权限:客户端/Bearer。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 400 | '缺少 token' |
| 403 | '无权撤销该令牌' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/revoke' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
ok | True |
实现定位:backend/cm_server.py:2811。接口参数和返回条件均来自该路由分支。
POST /cm/passport/token
授权码、刷新、客户端凭据换令牌
权限:客户端。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 401 | 'Basic 认证头解析失败' |
| 401 | 'client_id 无效或应用已停用' |
| 401 | 'client_secret 不正确' |
| 429 | '令牌请求过于频繁,请稍后再试' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/token'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
access_token | access |
token_type | 'Bearer' |
expires_in | cm_passport.ACCESS_TTL |
scope | scope |
sub | cm_db.passport_uid(uid) |
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
access_token | access |
token_type | 'Bearer' |
expires_in | cm_passport.ACCESS_TTL |
refresh_token | refresh |
refresh_expires_in | cm_passport.REFRESH_TTL |
scope | g['scope'] |
sub | cm_db.passport_uid(g['uid']) |
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
access_token | access |
token_type | 'Bearer' |
expires_in | cm_passport.ACCESS_TTL |
scope | scope |
实现定位:backend/cm_server.py:2622。接口参数和返回条件均来自该路由分支。
GET /cm/passport/userinfo
读取被授权账户信息
权限:Bearer。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 403 | '账号不可用' |
| 403 | '这是应用令牌(client_credentials),没有用户信息' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request GET 'https://music.20110208.xyz/cm/passport/userinfo' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
响应体 | out |
实现定位:backend/cm_server.py:2752。接口参数和返回条件均来自该路由分支。
POST /cm/passport/userinfo
通行证与应用授权 · /passport/userinfo
权限:路由未直接调用登录检查;委托处理器可能另行校验,见说明。
参数校验与业务错误
| HTTP | 服务端校验说明 |
|---|---|
| 403 | '账号不可用' |
| 403 | '这是应用令牌(client_credentials),没有用户信息' |
说明中的变量表达式表示运行时值;另有统一的认证、频控和上游错误。
请求模板
将 {id} 等占位符和字段值替换为实际数据,令牌只使用你自己的 CurrentMusic 会话。
curl --request POST 'https://music.20110208.xyz/cm/passport/userinfo' \
--header 'Authorization: Bearer YOUR_CURRENTMUSIC_TOKEN'
返回结构
以下是实现中直接返回的字段与取值表达式,不是一次真实请求的响应示例。条件分支可能返回不同结构。
HTTP 200
| 字段 | 取值/生成逻辑 |
|---|---|
响应体 | out |
实现定位:backend/cm_server.py:2752。接口参数和返回条件均来自该路由分支。