访问控制

您可以通过 Access Control 服务来控制对 Unity Gaming Services(Unity 游戏服务)(UGS) 的访问(包括对 Cloud Code 的访问)。

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

使用 Cloud Code 控制玩家经济的示例

以下示例演示了如何创建基于项目的策略来拒绝对 Economy 服务 increment/decrement API 的访问。由于玩家无法直接操作自己的余额,因此您可以创建一个 Cloud Code 模块,作为受信任的客户端代表玩家发出这些请求。

您可以使用 UGS CLI 工具应用访问策略。

先决条件

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

  1. Economy 服务中拥有已发布的货币
  2. 已设置 UGS CLI 以运行命令。如需了解更多信息,请参阅入门指南
  3. 已将项目级 Project Resource Policy Editor(项目资源策略编辑者)、Project Resource Policy Reader(项目资源策略读取者)和 Unity Environments Viewer(Unity 环境查看者)角色授予用来向 CLI 工具进行身份验证的服务帐户。

创建 Access Control 项目策略以限制访问

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

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

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

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

测试此策略是否成功拒绝了玩家在以玩家身份通过身份验证后直接向 increment API 终端发出的请求。

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 状态代码的响应:

{
    "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
}

创建模块终端

创建一个包含最新 Economy SDK 版本的 Cloud Code 模块来发出增加余额请求。模块函数接受 currencyId 作为参数以定义将余额更新应用于哪种货币。请确保此信息与 Economy 货币配置中的资源 ID 匹配。

using Microsoft.Extensions.DependencyInjection;
using Unity.Services.CloudCode.Apis;
using Unity.Services.CloudCode.Core;
using Unity.Services.CloudCode.Shared;
using Unity.Services.Economy.Model;

namespace Sample;

public class EconomySample
{
    [CloudCodeFunction("IncrementBalance")]
    public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IExecutionContext ctx,
        IGameApiClient gameApiClient, string currencyId)
    {
        try
        {
            return await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken,
                ctx.ProjectId, ctx.PlayerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));
        }
        catch (ApiException ex)
        {
            throw new Exception($"Failed to get increment {currencyId} currency for player: {ctx.PlayerId}. Error: {ex.Message}");
        }
    }

    public class ModuleConfig : ICloudCodeSetup
    {
        public void Setup(ICloudCodeConfig config)
        {
            config.Dependencies.AddSingleton(GameApiClient.Create());
        }
    }
}

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

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

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

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

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

验证模块

您可以通过 Unity Dashboard(Unity 后台)使用 Player Management(玩家管理)功能来确认玩家货币余额,或通过 Economy 服务 API 来请求余额以进行确认:

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

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