# 调用服务端 API 生成 Token (/zh-CN/realtime-media/whiteboard/fastboard-sdk/build/setup-and-access/generate-token-restful)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

本文介绍如何调用服务端 API 生成互动白板 Token。

## 功能介绍 [#功能介绍]

互动白板 Token 是互动白板服务对用户采用的一种鉴权方式。

你可以调用互动白板服务端 API 生成以下 Token：

- **SDK Token**：与特定的互动白板项目绑定，是级别最高的 Token。持有 SDK Token 的用户可操作该 Token 所绑定项目下的所有房间和文档转换任务。
- **Room Token**：与特定互动白板项目下的特定房间绑定。持有 Room Token 的用户可操作绑定的房间。
- **Task Token**：与特定项目下的特定文档转换任务绑定。持有 Task Token 的用户可操作绑定的文档转换任务。

调用互动白板服务端 API 生成每种 Token 时，你可以设置 Token 的角色（`role`）和有效时长（`lifespan`）：

- **角色**：包括 `admin`（管理员）、`writer`（读写）或 `reader`（只读）三种角色，每种角色的 Token 具有的权限详见[ Token 类型和权限](#token-的类型和权限)。
- **有效时长**：取值为正整数，单位为毫秒。生成 Token 的 UTC 时间加上你设置的有效时长，即 Token 的过期时间。Token 过期后，用户将无法再使用该 Token 加入房间或访问互动白板服务。为确保业务可用性，你需要及时生成新的 Token。

  :::caution[注意]
  - 如果你不设置 Token 的有效时长或将有效时长设为 0，生成的 Token 将永不过期。永不过期的 Token 可能为你的业务带来安全隐患。
  - 已经加入房间的用户不会因为 Token 过期被移出房间。
  - 项目被禁用或删除后，与之关联的访问密钥对也会被禁用或删除，所有使用该访问密钥对生成的 Token 都会失效。
  :::

## 前提条件 [#前提条件]

开始前，确保你已参考[开启和配置互动白板服务](/zh-CN/realtime-media/whiteboard/fastboard-sdk/build/setup-and-access/enable-service)完成了以下准备工作：

- 创建一个开启了互动白板服务的声网项目。
- 获取访问密钥 Access Key (AK) 和私有访问密钥 Secret Access Key (SK)。
- 如果你需要生成 Task Token 用于文档转换服务，则需要为项目开启并配置文档转换服务。

## 实现方法 [#实现方法]

本节介绍如何调用服务端 API 生成互动白板 Token。

### 生成 SDK Token [#生成-sdk-token]

生成 SDK Token 时，你需要传入项目的 AK 和 SK、Token 的有效时长和角色，详见[生成 SDK Token](/zh-CN/api-reference/api-ref/whiteboard/restful/generate-sdk-token)。以 cURL 为例：

```shell
curl --request POST \
  --url https://api.netless.link/v5/tokens/teams \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'region: cn-hz' \
  --data '{
  "accessKey": "BUxxxxxxrc",
  "secretAccessKey": "CxxxxxxxauY3",
  "lifespan": 3600000,
  "role": "admin"
}'
```

:::caution[注意]
SDK Token 的权限级别很高，如果泄漏，会危害你的业务安全。因此，声网建议：

- 不要将 SDK Token 暴露给客户端、存入数据库或写入配置文件，而是在需要时从业务服务端签出 SDK Token。
- 不要签出永不过期的 SDK Token，而是根据业务需要，设置 SDK Token 的有效时长。
:::

### 生成 Room Token [#生成-room-token]

生成 Room Token 时，你需要传入房间 UUID、SDK Token、Token 的有效时长和角色，其中房间 UUID 需要调用[POST 创建房间](/zh-CN/api-reference/api-ref/whiteboard/restful/create-room)获取，详见[生成 Room Token](/zh-CN/api-reference/api-ref/whiteboard/restful/generate-room-token)。以 cURL 为例：

```shell
curl --request POST \
  --url https://api.netless.link/v5/tokens/rooms/9e2xxxxxxxx356 \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'region: cn-hz' \
  --header 'token: NETLESSSDK_xxxxxxxxx' \
  --data '{
  "lifespan": 36000,
  "role": "admin"
}'
```

### 生成 Task Token [#生成-task-token]

生成 Task Token 时，你需要传入转换任务的 UUID、SDK Token、AK、Token 的有效时长和角色，其中转换任务的 UUID 需要调用[发起文档转换](/zh-CN/api-reference/api-ref/whiteboard/restful/start-file-conversion)获取，详见[生成 Task Token](/zh-CN/api-reference/api-ref/whiteboard/restful/generate-task-token)。以 cURL 为例：

```shell
curl --request POST \
  --url https://api.netless.link/v5/tokens/tasks/2fd2dxxxxx367e \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'region: cn-hz' \
  --header 'token: NETLESSSDK_xxxxxx' \
  --data '{
  "role": "writer",
  "lifespan": 36000,
  "ak": "T9xxxxxxxwkk"
}'
```

<a id="相关信息-1" aria-hidden="true"></a>

## 相关信息 [#相关信息]

### API 参考 [#api-参考]

- [生成 SDK Token](/zh-CN/api-reference/api-ref/whiteboard/restful/generate-sdk-token)
- [生成 Room Token](/zh-CN/api-reference/api-ref/whiteboard/restful/generate-room-token)
- [生成 Task Token](/zh-CN/api-reference/api-ref/whiteboard/restful/generate-task-token)

### Token 的类型和权限 [#token-的类型和权限]

本节介绍不同角色的三种 Token 所具有的权限。

#### SDK Token [#sdk-token]

| 权限 | admin（管理员） | writer（读写） | reader（只读） |
| --- | --- | --- | --- |
| 创建房间 | ✔ | ✔ | ✘ |
| 以互动模式加入房间 | ✔ | ✔ | ✘ |
| 以只读模式加入房间 | ✘ | ✘ | ✔ |
| 获取房间列表 | ✔ | ✔ | ✘ |
| 获取房间信息 | ✔ | ✔ | ✘ |
| 封禁房间 | ✔ | ✘ | ✘ |
| 对指定场景进行截图 | ✔ | ✔ | ✘ |
| 对场景组下的所有场景进行截图 | ✔ | ✔ | ✘ |
| 获取房间的场景地址列表 | ✔ | ✔ | ✘ |
| 插入新场景 | ✔ | ✔ | ✘ |
| 场景跳转 | ✔ | ✔ | ✘ |
| 发起文档转换任务 | ✔ | ✔ | ✘ |
| [generate-token-restful-markdown-0-13-0 details](#table-slot-generate-token-restful-markdown-0-13-0) | ✔ | ✔ | ✔ |
| [generate-token-restful-markdown-0-14-0 details](#table-slot-generate-token-restful-markdown-0-14-0) | ✔ | ✔ | ✔ |

<a id="table-slot-generate-token-restful-markdown-0-13-0"></a>

**generate-token-restful-markdown-0-13-0 details**

生成同等或以下角色的 Room Token
（例如，admin 角色的 SDK Token 可以生成
 `admin`、`writer` 或 `reader` 角色的 Room Token）

<a id="table-slot-generate-token-restful-markdown-0-14-0"></a>

**generate-token-restful-markdown-0-14-0 details**

生成同等或以下角色的 Task Token
（例如，admin 角色的 SDK Token 可以生成
 `admin`、`writer` 或 `reader` 角色的 Task Token）

#### Room Token [#room-token]

| 权限                         | admin（管理员） | writer（读写） | reader（只读） |
| :--------------------------- | :-------------- | :------------- | :------------- |
| 以[互动模式](/zh-CN/realtime-media/whiteboard/fastboard-sdk/build/setup-and-access/generate-token)加入特定房间       |  ✔               |  ✔             |✘               |
| 以[订阅模式](/zh-CN/realtime-media/whiteboard/fastboard-sdk/build/setup-and-access/generate-token)加入特定房间       | ✘                | ✘              |  ✔              |
| 获取特定房间信息             |  ✔             |  ✔              | ✘               |
| 封禁特定房间                 |  ✔              | ✘               | ✘               |
| 对指定场景进行截图           |  ✔           |  ✔              | ✘               |
| 对场景组下的所有场景进行截图 | ✔              |  ✔              | ✘               |
| 获取特定房间的场景地址列表   |  ✔              |  ✔             | ✘              |
| 在特定房间内插入新场景       |  ✔               | ✔              | ✘               |
| 特定房间内的场景跳转         | ✔              |  ✔              | ✘               |

#### Task Token [#task-token]

| 权限                       | admin（管理员）              | writer（读写）               | reader（只读）               |
| :------------------------- | :--------------------------- | :--------------------------- | :--------------------------- |
| 查询特定文档转换任务的进度 | ✔ | ✔ | ✔ |

<a id="token-相关错误-1" aria-hidden="true"></a>

### Token 相关错误 [#token-相关错误]

在使用 Token 访问互动白板服务时，你可能会遇到以下报错，你可以参考说明进行问题排查。

| 错误信息 | 说明 |
| --- | --- |
| `invalid format of token` | [generate-token-restful-markdown-1-1-1 details](#table-slot-generate-token-restful-markdown-1-1-1) |
| `expired token` | Token 已过期。请在 App 服务端调用互动白板 RESTful API 或用代码重新生成 Token。 |
| `invalid signature of token` | Token 的签名无效。当你使用在 App 服务端用代码生成的 Token 时，可能会遇到该报错。请确保使用正确的生成 Token 算法和代码。 |
| `unknown error` | 未知错误。 |
| `token access role$` `{发送过来的 token 的权限} forbidden` | Token 的权限过低，例如，使用 `reader` 角色的 Token 请求 `writer` 角色的 Token 才能访问的服务。请确保发起的请求与使用的 Token 权限一致。 |
| `token access task forbidden` | 禁止使用该 Task Token 访问 Task UUID 对应的文档转换任务。请确保请求中传入的 Task UUID 和 Task UUID 相匹配，即传入的 Task UUID 和生成该 Task Token 的 Task UUID 一致。 |
| `token access room forbidden` | 禁止使用该 Room Token 访问 Room UUID 对应的互动白板房间。请确保请求中传入的 Room UUID 和 Room UUID 相匹配，即传入的 Room UUID 和生成该 Room Token 的 Room UUID 一致。 |
| `token access team forbidden` | 项目被删除或禁用，导致 Token 失效。 |

<a id="table-slot-generate-token-restful-markdown-1-1-1"></a>

**generate-token-restful-markdown-1-1-1 details**

Token 的数据格式错误。请检查 Token 数据格式是否有效：

- Token 是否为 String 型。
- Token 前后是否有多余空格或字符。
- Token 的前缀是否正确：

  - SDK Token 的前缀为 `NETLESSSDK_`
  - Room Token 的前缀为 `NETLESSROOM_`
  - Task Token 的前缀为 `NETLESSTASK_`

### 通过其他方式生成 Token [#通过其他方式生成-token]

除调用服务端 API 生成外，你还可以通过以下方法生成互动白板 Token：

- 在[声网控制台](https://console.shengwang.cn/)生成 SDK Token。
- 在 App 服务端用代码生成 Token，详见[在 App 服务端生成 Token](/zh-CN/realtime-media/whiteboard/fastboard-sdk/build/setup-and-access/generate-token#在-app-服务端生成-token)。
