> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/advanced-topics/personal-access-token.md).

# 使用个人访问令牌

默认情况下，Convai Unreal Engine 插件会将你的 API 密钥存储在 `UConvaiSettings.API_Key` — 在 UE 5.2+ 中通过 Convai 编辑器窗口，或者在 `Config/DefaultEngine.ini` 中（适用于 UE 5.0 和 5.1）。这种流程适合编辑器测试和早期原型。在 **打包应用程序**中，任何检查该构建的人都可以读取已存储的 API 密钥，并将其用于你的 Convai 账户。

**个人访问令牌（PAT）** 可避免这种暴露。你的真实 API 密钥会保留在 **后端** — 你控制的服务端应用（Node.js、Python、.NET、AWS Lambda 等）。后端会调用 Convai 生成一个短期 `apiAuthToken` （有效期约一小时），并在运行时将其返回给你的 Unreal 项目。插件会在会话开始时发送该令牌。如果令牌被截获，它会在一小时内过期。

{% hint style="info" %}
**我应该使用这个吗？** 本地编辑器测试请使用常规 [配置您的 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/configure-your-api-key.md) 流程。发布打包构建且绝不能嵌入真实 API 密钥时，请使用个人访问令牌。
{% endhint %}

### 先决条件

* 已安装 Convai Unreal Engine 插件，并且你已使用常规 API 密钥完成一次成功的对话测试。请参见 [配置您的 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/configure-your-api-key.md) 是位于 [添加您的第一个 Convai 角色](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/add-your-first-convai-character.md).
* 一个你控制的后端，它可以将真实的 Convai API 密钥作为服务端机密进行存储。
* 从后端到 `https://api.convai.com`.

### 令牌流程如何工作

PAT 流程中有三个参与方：

| 角色            | 它持有什么              | 作用                                  |
| ------------- | ------------------ | ----------------------------------- |
| **后端**        | 真实的 Convai API 密钥  | 调用 Convai 令牌端点；绝不会将密钥暴露给 Unreal 构建。 |
| **Convai**    | 你的账户和角色            | 返回一个短期 `apiAuthToken`.              |
| **Unreal 项目** | 该 `apiAuthToken` 仅 | 在会话开始前将令牌设置到插件中。                    |

```mermaid
graph TD
    Backend["你的后端\n（保存真实 API 密钥）"]
    ConvaiAPI["Convai\nPOST /user/connect"]
    UnrealApp["Unreal 项目\n（接收 apiAuthToken）"]
    Session["Convai 会话\n(WebRTC)"]

    Backend -->|"CONVAI-API-KEY header"| ConvaiAPI
    ConvaiAPI -->|"apiAuthToken (~1 hour)"| Backend
    Backend -->|"运行时传递"| UnrealApp
    UnrealApp -->|"在开始会话前设置 AuthToken"| Session
```

Unreal 项目必须 **绝不能** 调用 `https://api.convai.com/user/connect` 直接调用。该端点需要真实 API 密钥——将其嵌入客户端会使 PAT 的目的失效。

### 在你的后端生成令牌

所有令牌端点都针对 `https://api.convai.com` 并且需要在 `CONVAI-API-KEY` header。请只从你的后端发起这些调用。

#### 生成令牌

```http
POST https://api.convai.com/user/connect
```

| Header           | 值                  |
| ---------------- | ------------------ |
| `Content-Type`   | `application/json` |
| `CONVAI-API-KEY` | 你的 Convai API 密钥   |

**请求体：** `{}`

**响应：**

```json
{
  "apiAuthToken": "eyJhbGciOi...",
  "expirationTime": "2024-01-15T14:30:00Z"
}
```

| 字段               | 说明                    |
| ---------------- | --------------------- |
| `apiAuthToken`   | 要交付给 Unreal 项目的短期令牌。  |
| `expirationTime` | UTC 过期时间戳——大约是生成后一小时。 |

当当前令牌仍然有效时，你可以生成一个新令牌。生成新令牌不会使之前的令牌失效。

**后端示例（Python）：**

```python
import requests

def get_api_auth_token(api_key: str) -> str:
    url = "https://api.convai.com/user/connect"
    headers = {
        "CONVAI-API-KEY": api_key,
        "Content-Type": "application/json",
    }
    response = requests.post(url, headers=headers, json={})
    response.raise_for_status()
    return response.json()["apiAuthToken"]
```

#### 延长令牌

```http
POST https://api.convai.com/user/extend-token
```

头部：与“生成”相同。

```json
{
  "apiAuthToken": "eyJhbGciOi..."
}
```

重置现有令牌的过期计时，但不会使其失效。

#### 撤销令牌

```http
POST https://api.convai.com/user/revoke-token
```

头部：与“生成”相同。

```json
{
  "apiAuthToken": "eyJhbGciOi..."
}
```

会立即使令牌失效。请在注销时或令牌不再需要时调用此操作。最好通过你的后端代理撤销流程，这样真实 API 密钥就永远不会随客户端一起发布。

### 在 Unreal Engine 中使用该令牌

插件通过以下方式读取凭据 `UConvaiUtils::GetAuthHeaderAndKey()`。当 `UConvaiSettings.API_Key` 为 **不为空**时，插件会使用 API 密钥及 `CONVAI-API-KEY` header。当 `API_Key` 为空，且 `AuthToken` 已设置时，插件会改为使用带有 `API-AUTH-TOKEN` header 的令牌。

生产环境 PAT 流程需要 **两个独立步骤**：在打包前从磁盘上的项目中移除 API 密钥 **在打包之前**，然后在运行时设置一个新的令牌 **之前** `开始会话`。跳过打包步骤会导致 `API_Key` 仍然包含在发布的构建中，即使你在编辑器的运行时清除了它。

| 组件                        | 当自动初始化运行时                                     | 何时设置令牌                                                 |
| ------------------------- | --------------------------------------------- | ------------------------------------------------------ |
| `UConvaiChatbotComponent` | `BeginPlay` 当 **Auto Initialize Session** 已启用 | 在该组件的 `BeginPlay` 完成之前——例如从 `GameMode` 或更早启动的 Actor 中。 |
| `UConvaiPlayerComponent`  | 当全局连接达到 `已连接`                                 | 在子系统报告 `已连接` 之前——不一定是在 `BeginPlay`.                    |

### 打包前清除 API 密钥

当你通过 Convai 编辑器窗口登录时，插件会写入 `API_Key` 到 `Config/DefaultEngine.ini`。Unreal Engine **会在打包构建中包含该文件**。如果 `API_Key` 如果你在打包时它仍然存在，那么真实密钥会随构建一起发布——运行时的 PAT 无法事后修复这种暴露。

完成此步骤 **之前** 你创建发布构建。请使用下面的方法之一。

{% tabs %}
{% tab title="注销（UE 5.2+）" %}
{% stepper %}
{% step %}

#### 打开账户菜单

在 Convai 编辑器窗口中，单击右上角的账户控件。
{% endstep %}

{% step %}

#### 退出登录

选择 **退出登录**。插件会清除 `API_Key` 是位于 `AuthToken` 来自 `Config/DefaultEngine.ini`.
{% endstep %}

{% step %}

#### 确认文件已清空

打开 `Config/DefaultEngine.ini` 并确认 `API_Key` 位于以下路径下的行 `[/Script/Convai.ConvaiSettings]` 为空或已移除。 **API 密钥** 中的字段 **Edit > Project Settings > Plugins > Convai** 也应为空。
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="编辑 DefaultEngine.ini（所有 UE 版本）" %}
{% stepper %}
{% step %}

#### 关闭编辑器

在编辑文件前关闭 Unreal Editor，以免你的更改在关闭时被覆盖。
{% endstep %}

{% step %}

#### 清除 API\_Key 和 AuthToken

打开 `Config/DefaultEngine.ini` 位于你的项目文件夹中。在 `[/Script/Convai.ConvaiSettings]`下，删除 `API_Key` 行，或者将其设置为空值。如果存在，也以同样方式清除 `AuthToken` 。

{% code title="Config/DefaultEngine.ini" %}

```ini
[/Script/Convai.ConvaiSettings]
API_Key=
AuthToken=
```

{% endcode %}
{% endstep %}

{% step %}

#### 打包前确认

重新启动编辑器并打开 **Edit > Project Settings > Plugins > Convai**。确认 **API 密钥** 为空，然后创建你的打包构建。
{% endstep %}
{% endstepper %}
{% endtab %}
{% endtabs %}

请参见 [移除或清除 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/configure-your-api-key.md#remove-or-clear-the-api-key) 了解本地凭据存储的完整参考。

### 在运行时设置令牌

在打包构建不再包含任何已存储的 API 密钥后，请在每次启动时从你的后端获取一个新的 `apiAuthToken` ，并在会话开始前将其应用 `开始会话`.

{% tabs %}
{% tab title="蓝图" %}
{% stepper %}
{% step %}

#### 从你的后端获取令牌

当玩家登录时——或在应用启动时——调用你的后端端点。使用你自己的应用会话对该请求进行身份验证（例如，来自登录系统的 bearer token）。你的后端返回 `apiAuthToken` 字符串。

不要在 `https://api.convai.com/user/connect` ，可通过 Blueprint 或任何客户端图形调用。
{% endstep %}

{% step %}

#### 清除任何内存中的 API 密钥

在同一个 Blueprint 图中，调用 **Set API Key** (`Convai|Settings`）并传入空字符串。这样会清除运行时仍加载在内存中的任何密钥。

你还必须完成 [打包前清除 API 密钥](#clear-the-api-key-before-packaging) 这样 `API_Key` 就不会出现在发布的 `DefaultEngine.ini`.
{% endstep %}

{% step %}

#### 设置认证令牌

调用 **Set Auth Token** (`Convai|Settings`）。将 `apiAuthToken` 来自后端响应的值连接到 **Auth Token** 输入引脚。
{% endstep %}

{% step %}

#### 启动或重新连接会话

如果 **Auto Initialize Session** 已启用，请在自动初始化触发前设置令牌——在 `BeginPlay` 用于 chatbot 组件，或者在全局连接达到 `已连接` 用于 player 组件。若时机不确定，请禁用 **Auto Initialize Session** 并调用 **开始会话** 在设置令牌后手动执行。

请参见 [会话生命周期](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/core-concepts/session-lifecycle.md) 用于手动会话控制。
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="C++" %}
包含 `ConvaiUtils.h` 并在 Convai 会话开始前设置令牌。调用 `UConvaiUtils::SetAPI_Key(TEXT(""))` 以清除运行时加载到内存中的任何密钥。

完成 [打包前清除 API 密钥](#clear-the-api-key-before-packaging) 先进行这样做，以便发布的 `DefaultEngine.ini` 不包含 `API_Key`.

{% code title="Source/MyProject/Private/PatSessionBootstrap.cpp" %}

```cpp
#include "ConvaiUtils.h"

void ApplyPersonalAccessToken(const FString& ApiAuthToken)
{
    // 当非空时，API_Key 优先——在仅 PAT 的生产构建中请清除它。
    UConvaiUtils::SetAPI_Key(TEXT(""));
    UConvaiUtils::SetAuthToken(ApiAuthToken);
}
```

{% endcode %}

调用 `ApplyPersonalAccessToken` 在你的后端 HTTP 请求完成之后，并在 `StartSession` 于 chatbot 或 player 组件上之前。若 **Auto Initialize Session** 已启用，请在早期启动期间应用令牌——从 `GameMode` 或 player controller `BeginPlay` 用于聊天机器人，并在全局连接达到 `已连接` 用于 player 组件之前。
{% endtab %}
{% endtabs %}

{% hint style="danger" %}
切勿直接从 Unity 应用调用 `https://api.convai.com/user/connect` 从 Unreal 项目中——这需要在客户端构建中包含真实的 API 密钥。不要将 `apiAuthToken` 写入打包构建中的磁盘；每次启动时都从你的后端获取一个新令牌。优先使用 `UConvaiUtils::SetAuthToken()` 而不是 `UConvaiSettings::SetAuthToken()` 来处理短期运行时令牌。
{% endhint %}

### 选择 Blueprint 或 C++

两条路径都会写入同一个 `UConvaiSettings.AuthToken` 字段。设置令牌后，插件行为完全相同。

| 项目类型                  | 推荐路径                                                                               |
| --------------------- | ---------------------------------------------------------------------------------- |
| 仅 Blueprint           | **Set Auth Token** 是位于 **Set API Key** 位于 \`Convai                                 |
| C++ 或混合 C++/Blueprint | `UConvaiUtils::SetAuthToken()` 是位于 `UConvaiUtils::SetAPI_Key()` 来自 `ConvaiUtils.h` |

选择与你的登录或会话引导已经所在位置相匹配的路径即可。仅 Blueprint 的项目通常不需要为了 PAT 设置而使用 C++。

### 令牌过期与会话

一旦 Convai WebRTC 会话开始，在该会话期间不会再次检查令牌。会话中途过期的令牌不会断开玩家连接。PAT 会在连接时被消耗。

| 场景                   | 行为                               |
| -------------------- | -------------------------------- |
| 令牌在以下操作之前过期 **开始会话** | 连接失败——从你的后端获取一个新令牌并重试。           |
| 令牌在活动会话期间过期          | 会话会持续到自然结束。                      |
| 令牌过期后重新启动应用          | 在启动时获取一个新令牌——不要在多个启动之间重复使用缓存的令牌。 |

你的后端可以调用 `/user/extend-token` ，或者在玩家开始新会话之前生成一个新令牌。

### 使用示例：企业培训终端

一个企业安全培训终端通过 LMS 后端验证每个学员。当学员登录时，后端会连同 LMS 会话数据一起返回一个 Convai PAT。Unreal 项目会清除任何嵌入的 API 密钥，设置该令牌，并开始对话。

```cpp
// PatKioskBootstrap.cpp — 伪代码模式
void APatKioskBootstrap::OnLearnerSignedIn(const FString& LmsSessionBearer)
{
    Backend->FetchConvaiToken(LmsSessionBearer, [this](const FString& ApiAuthToken)
    {
        UConvaiUtils::SetAPI_Key(TEXT(""));
        UConvaiUtils::SetAuthToken(ApiAuthToken);
        // 在 token 应用后，在 player/chatbot 组件上调用 StartSession。
    });
}
```

注销时，后端可以调用 `/user/revoke-token` 这样 PAT 就无法在共享设备上被重复使用。

### 故障排查

| 症状                          | 可能原因                                                       | 修复                                                                                                                                                                                                                                                       |
| --------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 连接立即失败                      | `apiAuthToken` 为 null——后端获取失败                              | 请验证你的后端 URL、身份验证头，以及后端是否返回了非空令牌字符串。                                                                                                                                                                                                                      |
| `401` 连接时身份验证错误             | 令牌在 **开始会话**                                               | 在开始会话前立即获取一个新令牌。                                                                                                                                                                                                                                         |
| PAT 被忽略；仍在使用 API 密钥         | `UConvaiSettings.API_Key` 仍然填充在 `Config/DefaultEngine.ini` | 从 Convai 编辑器窗口注销，在运行时调用 **Set API Key** 并传入空字符串，或者清除 `API_Key` 在 `Config/DefaultEngine.ini` 在打包前。请参见 [配置您的 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/configure-your-api-key.md#remove-or-clear-the-api-key). |
| 令牌在编辑器中有效，但在打包构建中失败         | 打包构建仍然包含已存储的 API 密钥，或者启动时没有获取 PAT                          | 确认运行时令牌获取在自动初始化前完成；从发布配置中清除嵌入的密钥。                                                                                                                                                                                                                        |
| `apiAuthToken` 在后端响应中为 null | 缺少 `CONVAI-API-KEY` header 或后端调用的正文格式错误                    | 请确保正文为 `{}` 并且 header 存在。记录原始后端响应。                                                                                                                                                                                                                       |

### 下一步

{% content-ref url="/pages/d6af0b14fc209017d2d18543ad38076bb0efe8f6" %}
[配置你的 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/configure-your-api-key.md)
{% endcontent-ref %}

{% content-ref url="/pages/a8878427b216a80d6b385f1a342c440aa9b398c9" %}
[会话生命周期](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/core-concepts/session-lifecycle.md)
{% endcontent-ref %}

{% content-ref url="/pages/54960e661fc090cc4ab31a059146f22c63a84ad3" %}
[Convai 实用函数](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/blueprint-reference/convai-utility-functions.md)
{% endcontent-ref %}

{% content-ref url="/pages/f1b3d71c37ea498f3d6d84fdf60594d3020ae6bf" %}
[连接和 API 密钥问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/troubleshooting/connection-and-api-key-issues.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/advanced-topics/personal-access-token.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
