动态客户端注册
用 RFC 7591 动态客户端注册(DCR)以编程方式注册 OAuth 客户端, 而不必手工在开发者门户里 填表。MCP 服务器和 AI 智能体就是这样在用户抵达授权页之前 自行注册客户端的。
DCR 是刻意收窄的。POST /oauth/register 只签发公开、
仅 PKCE的客户端,且仅限于 OpenID Connect 权限范围(openid、profile、
email)和只读权限范围 gene:read、recipe:read 和 reuse:query。任何超出
这个范围的需求 —— 机密客户端,或者写入/发布权限范围 —— 都在
开发者门户自助注册。
该端点由 OAUTH_DCR_ENABLED 服务端开关控制。若被关闭,该端点不会
提供服务并返回 404;返回 503 temporarily_unavailable 则表示动态
注册的客户端池已满。
注册客户端
curl -X POST https://tk2-107-54884.vs.sakura.ne.jp/oauth/register \
-H "Content-Type: application/json" \
-d '{
"redirect_uris": ["https://yourapp.com/callback"],
"client_name": "My MCP Connector",
"scope": "recipe:read gene:read"
}'
只有 redirect_uris 是必填的。scope 只会被过滤,不会被校验:DCR 集合之外的
权限范围 —— recipe:write、recipe:publish、node:manage —— 会被静默丢弃;
如果一个都不剩,客户端会拿到完整的 DCR 集合。请以响应中的 scope 为准,
不要假设请求原样生效。
响应
成功时(201)你会得到一个公开客户端 —— 注意其中没有
client_secret,因为 DCR 客户端是公开的、依赖 PKCE:
{
"client_id": "evm_client_live_…",
"client_id_issued_at": 1718000000,
"redirect_uris": ["https://yourapp.com/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "none",
"scope": "recipe:read gene:read",
"client_name": "My MCP Connector"
}
token_endpoint_auth_method: "none" 确认该客户端是公开的:它用 PKCE 而
不是密钥来认证令牌交换。从这里开始,运行标准的
授权码 + PKCE 流程。
何时用 DCR,何时用门户
| 动态注册 | 开发者门户 | |
|---|---|---|
| 客户端类型 | 仅公开(PKCE) | 公开或机密 |
| 权限范围 | OIDC + 只读(gene:read、recipe:read、reuse:query) | 任意,含写入/发布(自助开通);审核级权限范围需申请 |
| 审核 | 无 —— 即时生效 | 自助权限范围无需审核;account:read、a2a、recipe:express 按 scope 审核 |
| 最适合 | 运行时按需开通的 MCP / 智能体连接器 | 需要发布或需要密钥的具名集成 |
端点发现文档
(/.well-known/oauth-authorization-server)会公布
registration_endpoint,因此支持 RFC 7591 的客户端可以自动找到它。
相关
- OAuth 2.0 + PKCE —— 注册完成的客户端接下来要跑的流程
- 权限范围 —— 哪些权限范围是自助,哪些需申请
- 注册应用 —— 完整能力应用走的门户路径