# 인증

**URL:** https://heroiclabs.com/docs/kr/nakama/tutorials/unity/pirate-panic/authentication/
**Summary:** Pirate Panic 튜토리얼 게임에 인증을 추가하는 방법을 알아보세요.

---


# 인증

플레이어를 사용자로 설정하기, 다른 플레이어와 소통하기와 같이 멀티플레이어 게임에서 중요한 기능에 대해서 먼저 살펴보겠습니다.

Nakama를 사용하여 데이터가 저장되고 처리되는 **중앙 집중식 서버**를 쉽게 생성하고 플레이어(**클라이언트**)를 서버에 연결할 수 있습니다.

## 연결 설정

여기서 Unity 클라이언트와 Nakama 서버를 연결합니다.

첫 번째 단계는 게임이 Unity에서 시작되면 새로운 클라이언트 개체를 등록하는 것입니다. 이 개체는 클라이언트와 서버 사이에서 모든 상호 작용을 위한 인터페이스로 사용됩니다.

아래 항목은 클라이언트를 초기화하는 메인 메뉴 스크립트의 조각입니다:

**Scene01MainMenuController.cs**

```csharp
var client = new Client("http", "localhost", 7350, "defaultkey", UnityWebRequestAdapter.Instance);
client.Timeout = 5;
```

여기서, 다음의 연결 값을 전달하여 로컬로 시작한 서버(`http://localhost:7350`에서 사용 가능)로 연결을 생성합니다:

- `Scheme`: 연결 구성표는 `http` 여기를 참조하십시오.
- `Host`: 서버 호스트 `localhost`의 예시입니다.
- `Port`: 서버 포트는 기본적으로 `7350`(으)로 설정됩니다.
- `ServerKey`: 기본적으로, `defaultkey`이(가) 사용됩니다. [서버 구성](../../../../getting-started/configuration/#socket)을 통해 변경할 수 있습니다.

## 장치 인증

서버 연결을 완료하고 플레이어 인증을 진행하여 플레이어의 신원과 연결될 수 있도록 합니다.

Pirate Panic을 시작할 경우, 자동으로 인증이 완료되고 사용자 이름이 지정됩니다. 전화기 또는 컴퓨터 등 게임을 실행하는 장치와 연결되는 계정을 생성하는 장치 인증에서 원활한 인증이 진행됩니다.

Unity에서 장치 인증은 장치 ID를 `AuthenticateDeviceAsync`(으)로 전달하여 완료됩니다:

```csharp
string deviceId = SystemInfo.deviceUniqueIdentifier;
session = await client.AuthenticateDeviceAsync(deviceId);
```

{{< note "important" >}}
WebGL에 적용하는 경우, `deviceUniqueIdentifier` 대신에 `System.Guid.NewGuid().ToString()`을(를) 사용해야 할 수도 있습니다.
{{< / note >}}

인증이 완료된 경우, 플레이어는 로그인 시간을 표시하는 ***세션***에 참여합니다. 자세한 내용은 [세션](../../../../concepts/session/)을 참조하십시오.

세션 개체는 `Socket`와(과) `Account` 개체를 주로 사용하여 인증된 클라이언트로서 요청 사항을 전달하고 사용자 정보에 액세스할 수 있습니다:

```csharp
var socket = client.NewSocket(useMainThread: true);
await socket.ConnectAsync(session);
account = await client.GetAccountAsync(session);
```

Pirate Panic에서 `client`, `socket`, `account`, `session` 속성은 `GameConnection` 개체에 저장됩니다. 향후에 `_connection`(으)로 액세스하는 경우, 해당 속성을 참조한다는 점을 기억하시기 바랍니다.

{{< note "important" >}}
서버 연결을 원하는 대로 구성할 수 있지만, 다른 클래스에서 액세스할 수 있습니다.
{{< / note >}}

## Facebook 인증

장치 인증을 사용하면 플레이어가 쉽게 게임에 바로 진입할 수 있지만, 장치에 계정을 연결한 상태에서 장치가 손실 또는 재설정될 경우 계정이 소실됩니다. Facebook과 같은 외부 소셜 공급자를 통해 사용자 계정에 연결하면 추가적인 사용자 정보를 사용하여 문제를 해결할 수 있습니다.

{{< note "important" >}}
프로젝트 리포지토리를 복제한 경우 Facebook SDK가 Pirate Panic 코드에 포함됩니다. 자체 프로젝트를 시작하는 경우 [SDK](https://developers.facebook.com/docs/unity)가 있어야 합니다.
{{< / note >}}

Facebook SDK를 장면 스크립트에 포함시켜 다음과 같이 초기화합니다:

```csharp
using Facebook.Unity;
..
private void InitializeFacebook() {
    FB.Init(() =>
    {
        FB.ActivateApp();
    });
}
```

그런 다음, 아래의 조각이 로그를 처리합니다:

**ProfileUpdatePanel.cs**

```csharp
private void LinkFacebook()
{
    List<string> permissions = new List<string>();
    permissions.Add("public_profile");

    FB.LogInWithReadPermissions(permissions, async result =>
    {
        string facebookToken = result.AccessToken.TokenString;
        await _connection.Client.AuthenticateFacebookAsync(facebookToken);
    });
}
```

{{< note "important" >}}
`LinkFacebook`을(를) **Facebook 연결** 버튼으로 연결하여 플레이어가 자발적으로 로그인하는 시간을 선택할 수 있습니다.
{{< / note >}}

여기서 `public_profile` 권한을 제공하여 Nakama를 통해 이름 또는 프로필 사진과 같은 기본적인 사용자 정보에 액세스할 수 있습니다. [Facebook SDK 문서](https://developers.facebook.com/docs/unity)에서 참조할 수 있는 다른 권한과 기능도 추가할 수 있습니다.

Facebook에 로그인하면 플레이어의 Facebook 친구들이 게임 내의 [친구](../friends/) 목록에 자동으로 추가됩니다.

## 새로운 플레이어 초기화

플레이어가 로그인을 완료한 다음에는 초기 플레이어 정보를 설정해야 합니다. 이 작업이 완료되면, 플레이어는 친구를 추가하고, 보석을 모으고, 퀘스트를 완료하거나 사용자 데이터를 저장할 수 있습니다.

이 작업은 [등록 후크](../../../../server-framework/introduction/#hooks)를 사용하여 서버 측에서 처리할 수 있습니다. 인증 메서드마다 후크가 다릅니다. 예를 들어, 장치와 Facebook 인증을 설정하기 때문에 `registerAfterAuthenticateDevice`와(과) `registerAfterAuthenticateFacebook`을(를) 사용해야 합니다.

후크가 트리거될 때 실행되는 함수와 연결할 수 있습니다.

**main.ts**

```typescript
initializer.registerAfterAuthenticateDevice(afterAuthenticateDeviceFn);

const afterAuthenticateDeviceFn: nkruntime.AfterHookFunction<nkruntime.Session, nkruntime.AuthenticateDeviceRequest> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, data: nkruntime.Session, req: nkruntime.AuthenticateDeviceRequest) {
    afterAuthenticate(ctx, logger, nk, data);

    if (!data.created) {
        return; // Account already exists.
    }
    ...
    // Player initialization goes here. Write initial stats, add items to inventory, etc.
}
```

## 세션 토큰

보안상의 이유로 [Nakama 구성](../../../../getting-started/configuration/#common-properties)에서 정의된 시간이 지나면 플레이어 세션이 자동으로 만료됩니다. 플레이어가 다시 로그인하지 않아도 되도록 기존 세션이 만료되기 전에 새로운 세션을 자동으로 요청할 수 있게 메서드를 설정할 수 있습니다.

이 작업은 클라이언트에서 인증 **토큰**을 저장하고 서버에 새로운 토큰을 정기적으로 요청하여 처리할 수 있습니다.

두 가지 유형의 토큰이 있습니다:

- **액세스 토큰**: 클라이언트의 신원을 서버에 알려주고 해당 클라이언트를 신뢰할 수 있도록 합니다.
- **새로 고침 토큰**: 새로운 액세스 토큰을 요청할 때 사용합니다.

Nakama의 경우, `client` 개체를 사용하여 `SessionRefreshAsync`(으)로 새로운 토큰을 요청할 수 있습니다:

**Scene01MainMenuController.cs**

```csharp
string authToken = PlayerPrefs.GetString("nakama.authToken", null);
string refreshToken = PlayerPrefs.GetString("nakama.refreshToken", null);

session = Session.Restore(authToken, refreshToken);

// Check whether a session is close to expiry.
if (session.HasExpired(DateTime.UtcNow.AddDays(1))) {
    try {
        // get a new access token
        session = await client.SessionRefreshAsync(session);
    } catch (ApiResponseException) {
        // get a new refresh token
        session = await client.AuthenticateDeviceAsync(deviceId);
        PlayerPrefs.SetString("nakama.refreshToken", session.RefreshToken);
    }

    PlayerPrefs.SetString("nakama.authToken", session.AuthToken);
}
```

여기서는, Unity의 내장된 `PlayerPrefs` 엔진을 사용하여 액세스 토큰과 새로 고침 토큰을 각각 `nakama.authToken`와(과) `nakama.refreshToken`에 저장합니다.
세션 만료 전까지 하루 미만 남아있는 경우, 스크립트는 `SessionRefreshAsync`을(를) 사용하여 새로운 액세스 토큰을 요청합니다. 새로 고침 토큰이 유효하지 않은 경우, 해당 작업은 실패하고 모든 작업을 다시 인증해야 합니다.

## 다음 주제

[친구 및 채팅](../friends/)
