v1oauth 上下文
授权
POST /v1/oauth/preauthorize 与 POST /v1/oauth/authorize:同意页的两段式内部端点。
这两个端点是同意页专用的内部接口,不是给第三方客户端调的。第三方走标准授权码流程,见授权码流程。
它们把「用户看过并同意了这个应用的权限」变成服务端可验证的事实:先由 preauthorize 校验身份断言与回调地址并签发同意票据,再由 authorize 消费断言与票据、发码或拒绝。
POST /preauthorize
请求
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id_assertion | string | ✅ | 由 身份断言 签发的 JWE |
client_id | string | ✅ | 申请授权的客户端 |
redirect_uri | string | 可选 | 客户端使用的回调地址 |
scope | string | 可选 | 本次申请的 scope;缺省时取客户端注册的全集 |
响应
{
"success": true,
"can_skip_consent": false,
"client_name": "Example App",
"client_type": "third_party",
"client_logo_uri": null,
"client_uri": null,
"client_policy_uri": null,
"scopes": ["openid", "profile"],
"valid_redirect_uri": "https://app.example.com/callback",
"consent_ticket": "ct_..."
}| 字段 | 说明 |
|---|---|
can_skip_consent | 是否可跳过同意页面;不代表可以跳过票据 |
client_type | first_party 或 third_party |
client_*_uri | 展示素材,可空;页面按「有没有这一项」逐项显示或隐藏 |
scopes | 页面上要展示的 scope,由服务端算定并写进票据 |
valid_redirect_uri | 校验后的回调地址 |
consent_ticket | 不透明票据,30 分钟有效,只能兑换一次 |
校验顺序
- 身份断言解密、受众、过期、会话绑定;
- 断言一次性消费(同一枚断言最多换一张票据);
- 客户端存在且回调地址登记合法;
- 签发票据。
POST /authorize
请求
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id_assertion | string | ✅ | 点击那一刻现签的断言 |
consent_ticket | string | ✅ | preauthorize 返回的票据 |
decision | allow | deny | 可选 | 缺省 allow |
client_id | string | 可选 | 客户端标识 |
redirect_uri | string | 可选 | 回调地址 |
response_type | string | 可选 | 通常为 code |
scope | string | 可选 | 申请的 scope |
state | string | 可选 | 原样回传 |
code_challenge / code_challenge_method | string | 可选 | PKCE |
acr_values | string | 可选 | 目标认证强度 |
max_age | number | string | 可选 | 允许的最大认证年龄 |
authorization_details | unknown | 可选 | RFC 9396 细粒度授权 |
未声明的扩展参数会被保留并交给授权服务器库判断,不会被静默丢弃。
响应
{ "success": true, "redirect_to": "https://app.example.com/callback?code=...&state=..." }decision=deny 时 redirect_to 指向带 error=access_denied 的回调地址。
返回 JSON 而不是 302
调用方是 auth 前端,它必须留在自己的页面里决定何时跳转:直接把 302 交给浏览器,前端拿不到「授权已成功」这个结果,也无法在跳转前收尾。
更实际的问题是跨源:前端用 fetch 调这个端点时读不到 Location,302 因此不可用。
票据为什么必需
| 缺失的后果 | 说明 |
|---|---|
| 没有票据 | /authorize 就退化成「有断言就发码」,任何持有有效会话的人都能发码,同意页变成装饰 |
| 票据不含信息 | 账号、客户端、展示过的 scope、校验过的回调地址都在服务端记录里,调用方只带回随机串,比对基准不依赖调用方输入 |