# 服务令牌和访问令牌支持

> Use Access Tokens and Service Tokens to authenticate requests in Cloud Code scripts.

在脚本中，`context` 对象提供一个 `accessToken` 和一个 `serviceToken`：

| 令牌类型           | 来源                                                            | 数据访问         | 用途                                                                              |
| -------------- | ------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------- |
| `accessToken`  | 由 [Authentication 服务](/authentication/use-anon-sign-in.md)生成。 | 仅限经过身份验证的玩家。 | `AccessToken` 是用于对 Cloud Code 调用进行身份验证的 JWT。您可以将此令牌传递给其他 UGS 服务来访问经过身份验证的玩家的数据。 |
| `serviceToken` | 由 Cloud Code 生成。                                              | 跨玩家数据访问。     | `ServiceToken` 是用于调用其他 UGS 服务并处理跨玩家数据的令牌。                                       |

在调用其他 UGS 服务时，您可以使用这些令牌以玩家身份或 Cloud Code 身份进行身份验证。

请参阅[身份验证](./authentication.md)页面以了解更多信息。

## 概述##overview

请评估您是要以玩家身份还是以受信任的客户端身份进行身份验证。

脚本 `context` 对象为您提供一个 `accessToken` 和一个 `serviceToken`。

如果脚本的目的是仅访问经过身份验证的玩家的数据，则应使用 `accessToken` 以玩家身份进行身份验证来调用脚本。这将确保玩家只能访问和处理自己的数据。

如果脚本的目的是访问跨玩家数据，则应使用 `serviceToken` 以 Cloud Code 身份进行身份验证。这将确保脚本可以访问和处理跨玩家数据。但是，这为恶意玩家调用脚本并访问非预期跨玩家数据创造了机会。为防止出现这种情况，应确保模块受到[访问控制](./access-control.md)规则的保护。

要详细了解如何处理跨玩家数据，请参阅[跨玩家数据](./cross-player-data.md)文档。

## 访问令牌支持##access-token-support

访问令牌是 [Authentication 服务](/authentication/use-anon-sign-in.md)生成的 [JWT](https://jwt.io/)。您可以使用访问令牌对玩家进行身份验证。

当经过身份验证的玩家调用 Cloud Code 模块时，他们会将自己的访问令牌作为 `context` 对象的 `AccessToken` 属性传递给该模块。

您可以将访问令牌用于 Cloud Code JavaScript SDK。要将访问令牌用于其他 UGS API，您需要在 Authentication 标头中将令牌作为持有者令牌传递。

配置的[访问控制](./access-control.md)规则会影响 `accessToken`。

### 支持的服务##supported-services

要检查哪些服务支持访问令牌，请参阅下表：

| 提供者                       | 支持的服务                                                                                                          |
| ------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Cloud Code JavaScript SDK | 所有已接入 Authentication 服务的 [Cloud Code JavaScript SDK](https://cloud-code-sdk-documentation.cloud.unity3d.com/)。 |
| UGS Client API            | 所有已接入 Authentication 服务的 UGS 服务。                                                                               |
| UGS Admin API             | 不支持。改用[服务帐户身份验证](./authentication.md#cloud-code-admin-api-basic-authentication)。                               |

> **Note:**
>
> **注意：** 大多数 UGS 服务都接入了 Authentication 服务，并支持访问令牌。

### 将令牌用于 Cloud Code JavaScript SDK##use-tokens-with-cloud-code-javascript-sdks

要将 `accessToken` 用于 Cloud Code JavaScript SDK，您需要从 `context` 对象传递令牌。

> **Note:**
>
> **注意：** 默认情况下，Cloud Code JavaScript SDK 使用 `context` 对象中的 `serviceToken`。`accessToken` 需要显式传递给 SDK 构造函数才能使用。

以下示例将增加调用该脚本的玩家的货币余额。该脚本接受货币 ID 作为参数。

#### JavaScript##javascript

```javascript
const { CurrenciesApi } = require("@unity-services/economy-2.4");

module.exports = async ({ params, context, logger }) => {
  const { projectId, playerId, accessToken } = context;
  const { currencyId } = params;

  // Use the accessToken from the context object to authenticate the call as the player
  const currencies = new CurrenciesApi({accessToken});

  try {
    const result = await currencies.incrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 10 } });
    return result.data;
  } catch (err) {
    logger.error("Failed to update currency balance", {"error.message": err.message}, {"currencyId" : currencyId});
    throw err;
  }
}
```

### 将令牌用于 UGS Client API##use-tokens-with-ugs-client-apis

要将 `accessToken` 用于 UGS Client API，请在 Authentication 标头中将令牌作为持有者令牌传递。

> **Note:**
>
> **注意：** 如果要调用的服务提供了 Cloud Code JavaScript SDK，则可以使用该 SDK，而不是直接调用服务 API。如需查看可用 SDK 的列表，请参阅 [Cloud Code Services SDK](https://cloud-code-sdk-documentation.cloud.unity3d.com/) 页面。

以下示例将获取调用该脚本的玩家的好友列表：

#### JavaScript##javascript

```javascript
const axios = require("axios-0.21");

module.exports = async ({ params, context, logger }) => {
  const config = {
    headers: {
      'Content-Type': 'application/json',
      // Pass the accessToken from the context object as a bearer token
      Authorization: `Bearer ${context.accessToken}`
    }
  };

  try {
    const friendsGetUrl = `https://social.services.api.unity.com/v1/relationships?type=FRIEND_REQUEST`
    var res = await axios.get(friendsGetUrl, config);
    return res.data;
  } catch (err) {
    logger.error("Failed to retrieve Friends", {"error.message": err.message});
    throw err;
  }
};

```

## 服务令牌支持##service-token-support

服务令牌是 Cloud Code 生成的 [JWT](https://jwt.io/)。您可以使用服务令牌以 Cloud Code 身份对服务进行身份验证。这是经过[令牌交换](./authentication.md#cloud-code-client-api-bearer-authentication)过程的服务帐户令牌。

您可以将服务令牌用于 Cloud Code JavaScript SDK。要将其用于其他 API，您需要在 Authentication 标头中将其作为持有者令牌传递。

如需了解更多信息，请参阅[身份验证](./authentication.md#cloud-code-client-api-bearer-authentication)文档。

### 支持的服务##supported-services

如需查看支持服务令牌的服务列表，请参阅下表：

| 提供者                       | 支持的服务                                                                                                                                                                                                          |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Cloud Code JavaScript SDK | [Cloud Save][Cloud Save JS SDK][Economy][Economy JS SDK][Lobby][Lobby JS SDK][Leaderboards][Leaderboards JS SDK] [Player Names][Player Names JS SDK][Matchmaker][Matchmaker JS SDK][多人游戏][Multiplayer JS SDK]  |
| UGS Client API            | [Cloud Save][Cloud Save Client API][Economy][Economy Client API][Leaderboards][Leaderboards Client API] [Player Names][Player Names Client API][Matchmaker][Matchmaker Client API]                             |
| UGS Admin API             | 不支持。改用[服务帐户身份验证](./authentication.md#cloud-code-admin-api-basic-authentication)。                                                                                                                               |

如需了解更多信息，请参阅 [Cloud Code Services SDK](https://cloud-code-sdk-documentation.cloud.unity3d.com/) 文档。

[Cloud Save JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/cloud-save/v1.3

[Economy JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/economy/v2.4

[Lobby JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/lobby/v1.2

[Leaderboards JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/leaderboards/v1.1

[Player Names JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/player-names/v1.0

[Matchmaker JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/matchmaker/v2.0

[Multiplayer JS SDK]: https://cloud-code-sdk-documentation.cloud.unity3d.com/multiplay/v1.0

[Cloud Save Client API]: https://services.docs.unity.com/cloud-save/v1/

[Economy Client API]: https://services.docs.unity.com/economy/v2/

[Leaderboards Client API]: https://services.docs.unity.com/leaderboards/v1/

[Player Names Client API]: https://services.docs.unity.com/player-names/v1/

[Matchmaker Client API]: https://services.docs.unity.com/matchmaker/v2/

### 将令牌用于 Cloud Code JavaScript SDK##use-tokens-with-cloud-code-javascript-sdks

要将 `serviceToken` 用于 Cloud Code JavaScript SDK，请从 `context` 对象传递令牌。

以下示例接受一个玩家 ID 和一个货币 ID 作为参数并增加该玩家的货币余额：

#### JavaScript##javascript

```javascript
const { CurrenciesApi } = require("@unity-services/economy-2.4");

module.exports = async ({ params, context, logger }) => {
 const { projectId } = context;
 const { playerId, currencyId } = params;

  // By default, the Cloud Code JavaScript SDKs use the serviceToken from the context object
  const currencies = new CurrenciesApi(context);

  try {
    const result = await currencies.incrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 10 } });
    return result.data;
  } catch (err) {
    logger.error("Failed to update currency balance", {"error.message": err.message}, {"currencyId" : currencyId});
    throw err;
  }

}
```

### 将令牌用于 UGS Client API##use-tokens-with-ugs-client-apis

要将 `serviceToken` 用于 UGS Client API，请在 Authentication 标头中将令牌作为持有者令牌传递。

> **Note:**
>
> **注意：** 如果调用的服务提供了 Cloud Code C# SDK，则可以使用该 SDK，而不是直接调用服务 API。如需查看可用 SDK 的列表，请参阅[可用库](../reference/available-libraries)页面。

例如，如果您调用 Cloud Save API，则可以使用 `serviceToken` 进行身份验证并处理跨玩家数据。以下示例接受一个玩家 ID 作为函数参数，记录一个新值，并返回为该玩家存储的所有数据：

#### JavaScript##javascript

```javascript
const axios = require("axios-0.21");

module.exports = async ({ params, context, logger }) => {
  const config = {
    headers: {
      'Content-Type': 'application/json',
      // Authenticate as Cloud Code using the serviceToken from the context object
      Authorization: `Bearer ${context.serviceToken}`
    }
  };

  let result;
  try {
    const cloudSaveUrl = `https://cloud-save.services.api.unity.com/v1/data/projects/${context.projectId}/players/${params.playerId}/items`
    const payload = {
      key : "test",
      value: "test"
    };

    await axios.post(cloudSaveUrl, payload, config);
    result = await axios.get(cloudSaveUrl, config);

    return result.data;
  } catch (err) {
    logger.error("Failed to call out to Cloud Save", {"error.message": err.message});
    throw err;
  }
};
```
