OAuth 2.0 API
OAuth 2.0 Authorization Code + PKCE 授权服务器端点。第三方应用通过此 API 获取用户授权的 access_token。
基础路径
/oauth认证方式
/oauth/authorize(GET):无需认证(参数校验后重定向)/oauth/authorize(POST):需要 JWT(用户确认授权)/oauth/token:无需认证(公开端点)/oauth/revoke:无需认证(公开端点)/oauth/userinfo:Bearer Token(OAuth access_token)/oauth/apps/:clientId/public:无需认证(公开信息)
CORS 说明
/oauth/token、/oauth/revoke、/oauth/userinfo 允许所有 origin 跨域访问,其他端点使用默认 CORS。
端点列表
GET /oauth/authorize
发起 OAuth 授权流程。校验参数后 302 重定向到前端 consent 页。
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
response_type | string | 是 | 固定为 code |
client_id | string | 是 | OAuth App 的 client_id |
redirect_uri | string | 是 | 回调地址(必须在 App 注册的白名单中) |
scope | string | 否 | 请求的权限(空格分隔),默认使用 App 配置 |
state | string | 否 | 客户端随机值(建议必传,防 CSRF) |
code_challenge | string | 是 | PKCE code_challenge(BASE64URL 格式,43-128 字符) |
code_challenge_method | string | 是 | 固定为 S256 |
prompt | string | 否 | OIDC prompt 参数(空格分隔)。支持:login(强制重新登录)、consent、select_account(同 login)、none(无交互) |
login_hint | string | 否 | 预填邮箱,传到前端登录表单 |
display | string | 否 | 显示模式,仅支持 popup |
prompt 参数行为
| 值 | 行为 |
|---|---|
login / select_account | 即使已登录也强制重新登录 |
consent | 要求用户重新确认授权(当前每次都需确认,等效于默认行为) |
none | 不显示任何 UI。redirect 模式:302 到 redirect_uri 附带 error=interaction_required;popup 模式:由前端 postMessage 回传错误 |
注意:
none不可与其他值组合使用,否则返回invalid_request;未知值也返回invalid_request。
成功响应 302
重定向到前端 consent 页面:
{FRONTEND_BASE_URL}/oauth/consent?client_id=...&scope=...&state=...&prompt=...&login_hint=...错误响应 400
{
"error": "invalid_request",
"error_description": "Missing required parameter: client_id"
}GET /oauth/apps/:clientId/public
获取 OAuth 应用的公开信息(供 consent 页面展示)。
路径参数
| 参数 | 类型 | 说明 |
|---|---|---|
clientId | string | OAuth App 的 client_id |
成功响应 200
{
"name": "Page Agent",
"description": "AI 网页操控助手",
"logo_url": "https://example.com/logo.png",
"homepage_url": "https://example.com",
"redirect_uris": ["http://localhost:4100/callback"],
"scopes": ["chat:completions"],
"scope_descriptions": [
{ "scope": "profile:read", "description": "读取用户基本信息" },
{ "scope": "chat:completions", "description": "调用 AI 对话接口" }
]
}POST /oauth/authorize
用户确认授权,生成 authorization code。需要 JWT 认证。
请求体(JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
client_id | string | 是 | OAuth App 的 client_id |
redirect_uri | string | 是 | 回调地址 |
scope | string | 否 | 请求的权限 |
state | string | 否 | 客户端随机值 |
code_challenge | string | 是 | PKCE code_challenge |
code_challenge_method | string | 是 | 固定为 S256 |
成功响应 200
{
"redirectTo": "http://localhost:4100/callback?code=wno-code-...&state=..."
}前端收到后执行 window.location.assign(redirectTo) 完成跳转。
POST /oauth/token
换取 access_token 或刷新 token。
请求格式:application/x-www-form-urlencoded
grant_type=authorization_code
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
grant_type | string | 是 | authorization_code |
code | string | 是 | 授权码 |
client_id | string | 是 | client_id |
redirect_uri | string | 是 | 与授权请求时一致 |
code_verifier | string | 是 | PKCE code_verifier |
grant_type=refresh_token
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
grant_type | string | 是 | refresh_token |
refresh_token | string | 是 | refresh_token |
client_id | string | 是 | client_id |
成功响应 200
{
"access_token": "wno-...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "wno-rt-...",
"scope": "chat:completions"
}响应头:Cache-Control: no-store、Pragma: no-cache
错误响应
{
"error": "invalid_grant",
"error_description": "Authorization code expired or already used"
}POST /oauth/revoke
撤销 token(RFC 7009)。始终返回 200。
请求格式:application/x-www-form-urlencoded
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
token | string | 是 | 要撤销的 token(access 或 refresh) |
token_type_hint | string | 否 | access_token 或 refresh_token |
client_id | string | 否 | client_id |
响应 200
{}GET /oauth/userinfo
获取当前 OAuth 用户的基本信息。
请求头
Authorization: Bearer wno-...成功响应 200
{
"sub": "3be0c712-480d-43bf-971b-77e82ebbc428",
"email": "user@example.com",
"name": "用户名",
"avatar_url": "https://example.com/avatar.jpg",
"scope": "profile:read",
"is_site_admin": false
}错误响应 401
{
"error": "invalid_token",
"error_description": "Token expired or revoked"
}Admin OAuth Apps API
OAuth 应用管理端点。需要 JWT + site:admin 权限。
基础路径:/admin/oauth-apps
GET /admin/oauth-apps
列表(分页、搜索)。
查询参数
| 参数 | 类型 | 说明 |
|---|---|---|
page | number | 页码(默认 1) |
pageSize | number | 每页数量(默认 20) |
search | string | 搜索关键词(名称或 client_id) |
POST /admin/oauth-apps
创建应用。
请求体
{
"name": "My App",
"description": "描述",
"redirect_uris": ["https://example.com/callback"],
"scopes": ["chat:completions"],
"homepage_url": "https://example.com",
"logo_url": "https://example.com/logo.png"
}PATCH /admin/oauth-apps/:id
更新应用。scopes 或 redirect_uris 变更会撤销所有已发放的 token。
DELETE /admin/oauth-apps/:id
软删除 + 撤销所有关联 token。
POST /admin/oauth-apps/:id/disable
禁用应用 + 撤销所有 token。
POST /admin/oauth-apps/:id/enable
启用应用。