---
url: /zh/oauth/developer.md
description: |
  面向第三方开发者介绍 CNB OAuth 2.0 应用的接入流程， 包括应用登记、用户授权、临时票据获取及 API 访问控制的详细说明。
---
本文介绍 OAuth 2.0 应用的标准接入流程，涵盖应用登记上架、用户授权、临时票据发放及 API 访问控制。

## 准备工作：申请注册 OAuth 应用

### 应用信息登记

当前需要 CNB 运营管理员审核后上架应用，请将申请信息提交给管理员，管理员会与您沟通具体的创建方案。

### 应用基本信息

| 应用信息       | 是否必须 | 说明                                          |
| :------------- | :------- | :--------------------------------------------- |
| 应用名称       | 必须     | 授权时展示给用户，不超过 50 字                  |
| 应用 Logo      | 必须     | 图片大小不超过 1 MB                            |
| 应用简介       | 非必须   | 不超过 350 字                                   |
| 应用官网       | 必须     | 最多 128 字符                                  |
| 回调地址       | 必须     | Redirect URI，用于授权后重定向                  |
| 授权范围       | 必须     | 仅申请必要权限，平台审核时将评估合理性          |
| 授权资源范围   | 必须     | 当前账号所有资源 / 当前账号所有公开资源 / 指定资源 |

## 授权流程

用户在应用内的授权流程如下：

1. 用户在应用内发起 CNB 授权请求
2. 引导用户跳转至 CNB 授权页面，携带对应参数请求用户身份
3. 用户同意后，CNB 将附带授权临时票据 `code` 重定向到应用回调地址
4. 通过 `code`、`ClientID` 和 `ClientSecret` 调用 API 换取 `access_token`
5. 使用 `access_token` 调用接口，获取用户数据或执行操作

![](/images/oauth/7-oauth.png)

### 1. 发起授权请求

第三方网站应用可通过浏览器打开以下链接发起授权登录：

```text
https://cnbprod.alpha.qq.com/oauth2/auth?client_id=CLIENTID&redirect_uri=REDIRECT_URI&response_type=code&state=STATE
```

若提示「该链接无法访问」，请检查参数是否正确，例如 `redirect_uri` 的域名是否与审核时填写的授权域名一致。

以下为上述步骤所需的参数：

* `response_type`：授权类型，必填，固定值 `code`
* `client_id`：客户端 ID，必填
* `redirect_uri`：重定向 URI，可选
* `state`：客户端当前状态，可指定任意值，认证服务器会原样返回

举例如下：

```http
    GET /oauth2/auth?response_type=code&client_id=s6BhdRkqt3&state=xyz
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: cnbprod.alpha.qq.com
```

服务器返回的 URI 包含以下参数：

* `code`：授权码，必填，有效期通常为 10 分钟，仅可使用一次，与客户端 ID 和重定向 URI 一一对应
* `state`：若请求中包含此参数，响应中也必须包含相同的值

用户授权后将被重定向到 `redirect_uri` 指定的地址，并附带 `code` 和 `state` 参数。示例如下：

```http
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
```

### 2. 通过 code 获取 access\_token

客户端向认证服务器申请令牌，请求参数如下：

* `grant_type`：授权模式，必填，固定值 `authorization_code`
* `code`：上一步获得的授权码，必填
* `redirect_uri`：重定向 URI，可选，必须与第一步中的值一致

`client_id` 和 `client_secret` 也可通过 HTTP 基本认证（HTTP Basic Authentication），
以 Base64 编码形式包含在请求头的 `Authorization` 字段中发送。

```http
POST /oauth2/token HTTP/1.1
Host: cnbprod.alpha.qq.com
Authorization: Basic <Base64(client_id:client_secret)>
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
```

认证服务器返回的参数如下：

* `access_token`：访问令牌，有效期 8 小时，必填
* `token_type`：令牌类型，大小写不敏感，必填，可选 `bearer` 或 `mac`
* `expires_in`：过期时间，单位为秒。若省略，须通过其他方式设置过期时间
* `refresh_token`：刷新令牌，用于获取下一次的访问令牌，可选
* `scope`：权限范围，若与申请范围一致可省略

```http
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"bearer",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}
```

### 3. 通过 refresh\_token 更新令牌

`access_token` 有效期较短（8 小时），过期后可使用 `refresh_token` 刷新。
刷新后会返回新的令牌对，旧令牌在宽限期（5 分钟）内仍可使用。

`refresh_token` 有效期为 180 天，过期后需用户重新授权。

请求参数如下：

* `grant_type`：授权模式，必填，固定值 `refresh_token`
* `refresh_token`：之前获取的刷新令牌，必填

```http
POST /oauth2/token HTTP/1.1
Host: cnbprod.alpha.qq.com
Authorization: Basic <Base64(client_id:client_secret)>
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
```

返回示例与 `access_token` 相同。

### 4. 撤销令牌

用户退出登录或应用需主动使令牌失效时，可调用撤销接口吊销 `access_token` 或 `refresh_token`。撤销后令牌立即失效。

请求参数如下：

* `token`：需要撤销的令牌（`access_token` 或 `refresh_token`），必填
* `client_id`：客户端 ID，可选，也可通过 HTTP Basic Authentication 传递
* `client_secret`：客户端密钥，可选，也可通过 HTTP Basic Authentication 传递

`client_id` 和 `client_secret` 也可通过 HTTP 基本认证，以 Base64 编码形式包含在请求头的 `Authorization` 字段中发送。

```http
POST /oauth2/revoke HTTP/1.1
Host: cnbprod.alpha.qq.com
Authorization: Basic <Base64(client_id:client_secret)>
Content-Type: application/x-www-form-urlencoded

token=2YotnFZFEjr1zCsicMWpAA
```

认证服务器响应如下：

* 撤销成功：返回 HTTP `200`
* 令牌无效或已过期：同样返回 HTTP `200`（符合 RFC 7009 规范）
* `client_id`/`client_secret` 认证失败：返回 HTTP `401`

```http
HTTP/1.1 200 OK
```

认证失败响应示例：

```http
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
    "error": "invalid_client",
    "error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)."
}
```

## 可授权范围

| 可操作权限            | 权限类型 | 说明                                         |
| :-------------------- | :------- | :------------------------------------------- |
| repo-code             | 只读/读写 | 通过 Git 命令访问代码仓库                     |
| repo-pr               | 只读/读写 | 访问合并请求                                 |
| repo-issue            | 只读/读写 | 访问 ISSUE                                   |
| repo-notes            | 只读/读写 | 访问 ISSUE 及合并请求中的评论                 |
| repo-release          | 只读/读写 | 访问 tag、release                             |
| repo-commit-status    | 只读/读写 | 访问流水线状态、徽章、commit 元数据          |
| repo-cnb-trigger      | 只读/读写 | 查询、触发、执行云原生构建 / 云原生开发        |
| repo-cnb-history      | 只读     | 查询流水线构建历史                            |
| repo-cnb-detail       | 只读/读写 | 查询或删除云原生开发空间                      |
| repo-basic-info       | 只读     | 仓库基础信息（名称、描述、语言、license 等） |
| repo-manage           | 只读/读写 | 仓库成员与仓库设置                            |
| repo-delete           | 读写     | 删除仓库                                     |
| repo-security         | 只读     | 仓库安全模块数据                              |
| registry-package      | 只读/读写 | 访问制品                                     |
| registry-package-delete | 读写   | 删除制品                                     |
| registry-security     | 只读     | 制品安全、License、SBOM 数据                  |
| registry-manage       | 只读/读写 | 制品库成员与制品库设置                         |
| registry-delete       | 读写     | 删除制品库                                   |
| account-profile       | 只读/读写 | 用户个人资料                                 |
| account-email         | 只读/读写 | 查询用户认证邮箱                              |
| account-engage        | 只读/读写 | 关注的仓库、关注者、粉丝、云原生开发环境等    |
| group-resource        | 只读/读写 | 子组织与仓库                                  |
| group-manage          | 只读/读写 | 组织成员、仓库墙、组织设置                     |
| group-delete          | 读写     | 删除组织                                     |
| mission-delete        | 读写     | 删除任务集                                   |
| mission-manage        | 只读/读写 | 访问任务集                                   |
