# 액세스 제어

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

[액세스 제어 서비스](/services/access-control.md)를 통해 Cloud Code를 비롯한 Unity Gaming Services(UGS)에 대한 액세스를 제어할 수 있습니다.

액세스 제어를 사용하면 서비스 API에 대한 플레이어의 액세스를 제한하는 규칙을 만들어 플레이어의 액세스를 차단할 수 있습니다.

> **Note:**
>
> 모듈에 대한 플레이어 액세스를 허용하면 게임의 보안이 약화됩니다. 자세한 내용은 [서버 권한](../../server-authority)을 참고하십시오.

## Cloud Code로 플레이어 경제를 제어하는 예시##control-player-economies-with-cloud-code-example

아래 예시는 [Economy 서비스](/economy.md)의 증액/감액 API에 대한 액세스를 거부하는 프로젝트 기반 정책을 생성하는 방법을 보여 줍니다. 플레이어가 자신의 잔액을 직접 조작할 수 없으므로, 개발자는 플레이어를 대신하여 [신뢰할 수 있는 클라이언트](./authentication.md#authenticate-trusted-clients)로서 이러한 요청을 수행하는 Cloud Code 모듈을 만들 수 있습니다.

[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. CLI 툴로 인증하는 데 사용하는 서비스 계정에 프로젝트 레벨의 프로젝트 리소스 정책 편집자, 프로젝트 리소스 정책 독자, Unity 환경 조회자 역할이 부여된 상태입니다.

### 액세스를 제한하는 액세스 제어 프로젝트 정책 생성##create-an-access-control-project-policy-to-restrict-access

다음과 같은 내용으로 `project-policy.json` 파일을 생성하여 Economy 서비스의 증액 및 감액 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
}
```

### 모듈 엔드포인트 생성##create-a-module-endpoint

잔액의 증액을 요청할 수 있도록 최신 Economy SDK 버전이 포함된 Cloud Code 모듈을 [생성](./write-modules.md)합니다. 이 모듈 함수는 `currencyId`를 파라미터로 사용하여 잔액 업데이트를 적용할 재화를 정의합니다. 이 값은 Economy 재화 구성의 리소스 ID와 일치해야 합니다.

```csharp
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());
        }
    }
}
```

> **Important:**
>
> **중요**: Economy SDK의 기본 인증에서는 버전 2.4 이상의 Cloud Code 서비스 계정을 사용하며, 2.3 이하의 버전을 사용하는 경우에는 플레이어로 인증합니다.

플레이어로 인증된 경우 Cloud Code 모듈이 잔액을 증액할 수 있는지 테스트합니다.

```bash
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 상태 코드를 사용하여 새로운 잔액이 포함된 증액 요청 결과로 응답합니다.

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

### 모듈 유효성 검사##validating-the-module

플레이어의 재화 잔액은 Unity Dashboard에서 [플레이어 관리](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를 성공적으로 설정했다면 예상되는 경우에만 플레이어의 잔액을 업데이트하는 추가 로직을 삽입할 수 있습니다.
