fix: v2.3.2 用探测确定真实 scope 词表,接入已实测可用
- 上一版默认 scope 名是猜的(account.read / email_routing.write),全部被拒。 正确词表是点号分隔的 <group>.<verb>,且: - 账号是 account-settings.read(选择器里叫 Account Settings Read),不是 account.read - Workers 脚本是 workers-scripts.write,不是 workers_scripts.write - Email Routing 在选择器里是四个独立权限,改 catch-all 对应 email-routing-rule.write - account:read 这种冒号写法是 wrangler 的第一方简写,第三方 client 一律被拒 - client 注册的 scope 是上限不是默认:没勾的权限即使账号有也不生效 - preflight 扩展 scope 探测:授权端点在同意页之前就校验并点名拒绝的 scope, 逐轮「请求剩余候选 -> 剔除被点名项」即可收敛出 App 已授权集合(未认证请求, 不登录/不产生授权),结果按 allowed/denied 返回并在设置页用绿/橙标签展示 - 缺少账号级读权限时不再失败:discover() 先试 /accounts,403 则改为列 token 可见的 /zones, 用 zone 自带的 account_id 反推账户(展示名用第一个域名) - 默认 scope 收敛为接入必需的三项(zone.read / workers-scripts.write / email-routing-rule.write),account-settings.read 改为可选:勾了才显示真实账号名 - 实测:线上 preflight 已 ok=true(Cloudflare 跳登录页),无需再改 App 即可「添加账号」
This commit is contained in:
@@ -61,16 +61,34 @@ Cloudflare Dashboard 登记的回调地址),`GET /api/oauth/mode` 返回 `source
|
||||
| Promote to public | 应用可见性从 private 提升为 public | 私有 App 不可被他人授权 |
|
||||
| Scopes | 与 Console「设置 → Cloudflare 接入」里的 scope 字段**逐字一致** | `invalid_scope`: Client is not allowed to request scope '...' |
|
||||
|
||||
### scope 必须是点号分隔
|
||||
### scope 词表与选择器的对应关系
|
||||
|
||||
Cloudflare OAuth 的 scope 命名是 `account.read` 这种**点号**形式;冒号形式(`account:read`)不被接受,
|
||||
授权端点会判为 `invalid_scope`。默认请求的四个:
|
||||
Cloudflare 第三方 OAuth 客户端的 scope 是 **点号分隔** 的 `<group>.<verb>`。`account:read` 这种冒号写法
|
||||
是 **wrangler 的第一方简写**,第三方客户端请求会被一律拒绝(它只对第一方 client 生效)。权威列表是
|
||||
`GET /client/v4/oauth/scopes`,选择器里是它的可勾选项。
|
||||
|
||||
```text
|
||||
account.read zone.read email_routing.write workers_scripts.write
|
||||
```
|
||||
本应用默认请求这四个(已在 Cloudflare 侧逐个验证可被接受):
|
||||
|
||||
Console 允许在设置里改这个字段,以便与 App 中登记的值保持一致(`settings.cf_oauth_scopes`)。
|
||||
| scope id | 选择器里的名称 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `account-settings.read` | Account Settings Read | 列出账号(拿账号名) |
|
||||
| `zone.read` | Zone Read | 发现该账号下的域名 |
|
||||
| `workers-scripts.write` | Workers Scripts Edit | 上传账号级 Email Worker 脚本 |
|
||||
| `email-routing-rule.write` | Email Routing Rules Edit | 开启 Email Routing + 配置 catch-all 规则 |
|
||||
|
||||
两个容易踩的点:
|
||||
|
||||
- **Email Routing 在选择器里是四个独立权限**(`Email Routing Account Rules` / `Addresses` /
|
||||
`Rules` / `Suppressions`),不是笼统的"email routing 写"。改 catch-all 规则对应上面表里的
|
||||
`email-routing-rule.write`。
|
||||
- **客户端注册的 scope 是上限,不是默认值**。App 里没勾的权限,即使账号本身有,授权时也不会生效;
|
||||
反过来请求里不写某个 scope,即使 App 勾了也不会被授予。
|
||||
|
||||
### 缺少账号级读权限时的降级(2026-09-30 实测后加入)
|
||||
|
||||
若 App 没有勾 `account-settings.read`,`GET /accounts` 会 403。Console 会自动降级:直接列 token 可见的
|
||||
`/zones`,用 zone 自带的 `account_id` 反推目标账户,账号展示名用第一个域名代替(如 `example.com 等 3 个域名`)。
|
||||
因此**只勾 `zone.read` + `workers-scripts.write` + `email-routing-rule.write` 也能完成接入**,只是账号名显示为域名。
|
||||
|
||||
## 授权配置自检(不用开浏览器)
|
||||
|
||||
@@ -81,3 +99,18 @@ Console 允许在设置里改这个字段,以便与 App 中登记的值保持一
|
||||
`error_description` 与一条处置建议。
|
||||
|
||||
设置页「Cloudflare 接入」tab 的「检测授权配置」按钮就是调它。纯只读探测,不会产生任何授权。
|
||||
|
||||
### scope 探测:直接算出"哪些已授权、哪些还要勾"
|
||||
|
||||
授权端点在**显示同意页之前**就校验 scope,拒绝时通过 `error_description` **点名**是哪一个
|
||||
(`... not allowed to request scope 'xxx'`)。于是可以逐轮「请求剩余候选 → 剔除被点名的那一个」,
|
||||
收敛出该 App 实际持有的 scope 集合——每轮只是一个未认证请求,无需登录、无需同意、不产生任何授权。
|
||||
|
||||
`preflight` 在收到 `invalid_scope` 时会自动跑完这个探测,并在结果里返回:
|
||||
|
||||
```json
|
||||
"scopes": { "allowed": ["zone.read", "workers-scripts.write"],
|
||||
"denied": ["account-settings.read"], "probed": true, "note": null }
|
||||
```
|
||||
|
||||
设置页把两列分别渲染成绿色/橙色标签,「待勾选」列就是需要在 OAuth App 选择器里补上的权限。
|
||||
|
||||
Reference in New Issue
Block a user