# 访问控制

> Control access to Unity Gaming Services by creating rules to restrict service APIs you want to protect.

您可以通过 [Access Control 服务](/services/access-control.md)来控制对 Unity Gaming Services（Unity 游戏服务）(UGS) 的访问（包括对 Cloud Code 的访问）。

通过 Access Control，您可以创建规则来限制访问不想提供给玩家的服务 API。

> **Note:**
>
> 如果您允许玩家访问 API，游戏的安全性会降低。如需了解更多信息，请参阅[服务器权威](../../server-authority)。

## 使用 Cloud Code 控制玩家经济的示例##control-player-economies-with-cloud-code-example

以下示例演示了如何创建基于项目的策略来拒绝对 [Economy 服务](/economy.md) increment/decrement API 的访问。由于玩家无法直接操作自己的余额，因此您可以创建一个 Cloud Code 脚本，作为[受信任的客户端](./authentication.md#authenticate-trusted-clients)代表玩家发出这些请求。

您可以使用 [UGS CLI 工具](https://services.docs.unity.com/guides/ugs-cli/latest/access/Access%20Command%20Line/overview/)应用访问策略。

### 先决条件##prerequisites

在继续该示例之前，请确保项目满足以下先决条件：

1. 在 [Economy 服务](/economy.md)中拥有[已发布的货币](/economy/publication.md)。
2. 已设置 UGS CLI 以运行命令。如需了解更多信息，请参阅[入门指南](https://services.docs.unity.com/guides/ugs-cli/latest/general/overview/)。
3. 已将项目级 Project Resource Policy Editor（项目资源策略编辑者）、Project Resource Policy Reader（项目资源策略读取者）和 Unity Environments Viewer（Unity 环境查看者）角色授予用来向 CLI 工具进行身份验证的服务帐户。

### 创建 Access Control 项目策略以限制访问##create-an-access-control-project-policy-to-restrict-access

创建一个包含以下内容的 `project-policy.json` 文件，从而创建一个策略，拒绝玩家直接访问 Economy 服务中的 increment 和 decrement API。

```json
{
  "statements": [
    {
      "Sid": "DenyPlayerAccessForEconomyIncrementAndDecrement",
      "Resource": "urn:ugs:economy:/*/*crement",
      "Principal": "Player",
      "Action": ["*"],
      "Effect": "Deny"
    }
  ]
}
```

使用 UGS CLI 工具将此策略应用于您的项目：

```bash
ugs access upsert-project-policy project-policy.json
```

测试此策略是否成功拒绝了玩家在[以玩家身份通过身份验证后](./authentication.md#authenticate-players)直接向 `increment` API 终端发出的请求。

```bash
curl 'https://economy.services.api.unity.com/v2/projects/<PROJECT_ID>/players/<PLAYER_ID>/currencies/<CURRENCY_ID>/increment' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>' \
--data '{
    "amount": 10
}'
```

如果已成功应用此策略，该请求应返回包含 `403` HTTP 状态代码的响应：

```json
{
    "status": 403,
    "title": "Forbidden",
    "type": "https://services.docs.unity.com/docs/errors/#56",
    "requestId": "b815d154-91f5-470e-a8ef-76c3c8ec7c13",
    "detail": "Access has been restricted",
    "code": 56
}
```

### 创建并发布 Cloud Code 脚本##create-and-publish-a-cloud-code-script

[创建并发布](./write-scripts.md)一个包含最新 Economy SDK 版本的 Cloud Code 脚本来发出增加余额请求。此脚本接受 `currencyId` 作为脚本参数以定义将余额更新应用于哪种货币。请确保此信息与 Economy 货币配置中的资源 ID 匹配。

#### JavaScript##javascript

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

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

 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;
  }
}

module.exports.params = {
  "currencyId" : { "type": "String", "required": true }
}
```

> **Important:**
>
> **重要**：从版本 2.4 开始，Economy SDK 默认身份验证使用 Cloud Code 服务帐户。如果版本为 2.3 及更低版本，则会以玩家身份进行身份验证。

测试 Cloud Code 脚本在以玩家身份进行身份验证后是否能够增加余额。

```bash
curl --request POST 'https://cloud-code.services.api.unity.com/v1/projects/<PROJECT_ID>/scripts/<SCRIPT_NAME>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>'
--data '{"currencyId": "<CURRENCY_ID>"}'
```

如果余额更新请求成功，Cloud Code 应以 `200` HTTP 状态代码和包含新余额值的增加余额请求结果进行响应。

```json
{
  "result": {
    "balance": 10,
    "created": {
      "date": "2023-06-30T09:12:54Z"
    },
    "currencyId": "GOLD",
    "modified": {
      "date": "2023-06-30T09:12:54Z"
    },
    "writeLock": "1"
  }
}
```

### 验证脚本##validating-the-script

您可以通过 Unity Dashboard 使用 [Player Management（玩家管理）](https://cloud.unity.com/player-management)功能来确认玩家货币余额，或通过 Economy 服务 API 来请求余额以进行确认：

```bash
curl 'https://economy.services.api.unity.com/v2/projects/<PROJECT_ID>/players/<PLAYER_ID>/currencies' \
--header 'Authorization: Bearer <BEARER_TOKEN>'
```

成功设置 Cloud Code 以控制玩家余额后，您可以插入其他逻辑，以确保玩家的余额仅在需要时更新。
