20. Deprecated - iFun Authenticator

Attention

본 문서에서 설명하는 iFun Authenticator 를 이용한 인증 검증 기능은 Deprecated 되어 제거될 예정입니다. 외부 서비스 지원 Part 1: 인증 검증 에서 설명하는 각 플랫폼별 인증 검증 기능을 사용하시기 바랍니다.

If you are using external platforms like Facebook or Google Plus, you need to implement user authentication on both the client and server side. This means using the relevant platform’s SDK in the game client to authenticate and sending a key to the game server to judge authentication, then testing key validity on the game server.

Most platforms only provide client-side authentication with server-side authentication not supported. For that reason, the more platforms that are connected, the greater the burden on the server developer. iFun Engine provides a feature for server-side authentication on major platforms along with features for retrieving friends lists, nicknames, etc.

20.1. iFun Authenticator

iFun Engine uses a program called iFun Authenticator as an agent to exclusively handle authentication. The game server sends authentication requests to iFun Authenticator, and iFun Authenticator authenticates each actual platform.

Note

iFun Engine’s use of a separate authentication agent doesn’t affect game servers and is so that new authentication can be added or changed.

With the use of an agent, it is easy to use authentication services through the agent’s REST API on the game server and other servers as well.

20.1.1. Supported platforms

Authentication is supported on the following external platforms. (We plan to expand authentication support to more platforms in future.)

  • Facebook
  • Twitter
  • Google+
  • Nexon Toy

20.1.2. How to install

Tip

If Game server-side authentication parameters‘s use_authenticator is set to false, the game server runs in test mode and assumes all authentication requests are bypassed. This setting is used during the development phase, and there is no need to install iFun Authenticator in these instances.

20.1.2.1. For Ubuntu

$ sudo apt-get update
$ sudo apt-get install funapi-authenticator1

20.1.2.2. For CentOS

$ sudo yum install funapi-authenticator1

20.1.3. How to execute

20.1.3.1. For Ubuntu 14.04 or CentOS 6

Open the file /etc/default/funapi-authenticator and modify enabled=1.

Run the following command:

$ sudo service funapi-authenticator start

20.1.3.2. For Ubuntu 16.04 or CentOS 7

Run the following command:

$ sudo systemctl enable funapi-authenticator
$ sudo systemctl start funapi-authenticator

20.1.4. Checking operation

20.1.4.1. For Ubuntu 14.04 or CentOS 6

$ sudo service funapi-authenticator status

20.1.4.2. For Ubuntu 16.04 or CentOS 7

$ sudo systemctl status funapi-authenticator

20.1.4.3. Log file

Logs are output to /var/log/funapi/funapi-authenticator/.

20.1.5. Setting up iFun Authenticator (MANIFEST.json)

Note

This is to set up iFun Authenticator itself. Settings for game servers using iFun Authenticator are in Game server-side authentication parameters.

iFun Authenticator was, of course, also written with iFun Engine. Therefore, you can naturally change settings in iFun Authenticator’s MANIFEST.json. iFun Authenticator’s MANIFEST.json is in /usr/share/funapi-authenticator/default/manifests/MANIFEST.json.

Configure as follows.

  • tcp_listen_port: Sets the TCP port number for the iFun Engine game server to communicate with iFun Authenticator. (type=uint16, default=12800)
  • http_listen_port: Sets the HTTP port to communicate with iFun Authenticator through REST API. (type=uint16, default=12801)
  • bypass: Whether or not to bypass all authentication. Runs iFun Authenticator in test mode. This has the same effect as setting use_authenticator=false on the iFun Engine game server. (type=bool, default=false)
  • ip_address_table_path: Sets the path for the table file listing server IPs that can send requests to iFun Authenticator. You need to set this as the relative path from /usr/share/funapi-authenticator/default/resources/. (type=string, default=”acl/ip_address_table”)

Tip

When the agent is updated, the existing MANIFEST.json is overwritten. To prevent this, you can use an override file as described in Temporarily overriding MANIFEST.json.

{
  "override": {
    "FunapiAuthenticatorServer": {
      "tcp_listen_port": 8070,
      "http_listen_port": 8080,
      ...
    },
    ...
  }
}

20.2. Authentication

You can use the function provided by iFun Engine (in this case, communication is through TCP) or independently use RESTful API.

20.2.1. Invoking the iFun Engine function

iFun Engine uses a single authentication request interface regardless of platform type. It provides both asynchronous and synchronous functions.

1
2
3
4
5
void Authenticate(const AccountAuthenticationRequest &request,
                  const AuthenticationResponseHandler &handler);

bool AuthenticateSync(const AccountAuthenticationRequest &request,
                      AccountAuthenticationResponse *response);
1
2
3
4
5
public static void Authenticate(Authentication.AccountAuthRequest request,
                                Authentication.AuthResponseHandler handler);

public static bool AuthenticateSync(Authentication.AccountAuthRequest request,
                                    out Authentication.AccountAuthResponse response);

AccountAuthenticationRequest object must be initialized with the following:

1
2
3
AccountAuthenticationRequest(const string &service_provider,
                             const string &local_account,
                             const AuthenticationKey &key);
1
2
3
public AccountAuthRequest(string service_provider,
                          string local_account,
                          string auth_key);

The details are as follows:

  • service_provider: Name of the service provider, must be one of:
    • Facebook: Facebook Service
    • GooglePlus: Google+ Service
    • NexonToy: Nexon Toy Service
  • local_account: Unique identifier for user account(e.g., facebook uuid can be used as unique identifier).
  • key: This contains key information. Creation method can be different depend on platform as follows:
1
2
3
4
5
6
7
8
9
AuthenticationKey MakeFacebookAuthenticationKey(const string &facebook_access_token)

AuthenticationKey MakeGooglePlusAuthenticationKey(const string &google_client_id,
                                                  const string &google_access_token)

AuthenticationKey MakeNexonToyAuthenticationKey(int64_t svc_id,
                                                const string &client_id,
                                                const string &np_sn,
                                                const string &np_token)
1
2
3
4
5
6
7
8
9
public static string MakeFacebookAuthKey(string facebook_access_token);

public static string MakeGooglePlusAuthKey(string google_client_id,
                                              string google_access_token);

public static string MakeNexonToyAuthKey(long svc_id,
                                             string client_id,
                                             string np_sn,
                                             string np_token);

Tip

See API documentation for more details.

20.2.1.1. Example: Facebook authentication

The game client contacts Facebook’s authentication server to authenticate Facebook and inputs the Facebook ID and password to receive an access token. When this access token is sent from the game client to the game server, the game server can check its validity as follows:

20.2.1.1.1. Synchronous approach

Use AuthenticateSync() as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void example(const string &fb_uid, const string &fb_access_token) {
  AuthenticationKey auth_key = MakeFacebookAuthenticationKey(access_token);

  // 아래는 인증 요청 정보를 만드는 것입니다.
  // 첫번째 인자는 인증 플랫폼 종류를 뜻합니다.
  AccountAuthenticationRequest req("Facebook", fb_uid, auth_key);
  AccountAuthenticationResponse rep;

  if (not AuthenticateSync(req, &rep)) {
    LOG(ERROR) << "authentication system error";
    return;
  }

  // 오류는 발생하지 않았지만, 인증 결과가 실패한 경우입니다.
  // 클라이언트가 가짜로 access token 을 만들어 보내는 경우 등이 포함됩니다.
  if (not rep.success) {
    LOG(INFO) << "login failed. code(" << rep.reason_code << "),"
              << "description(" << rep.reason_description << ")";
    return;
  }

  LOG(INFO) << "login success";
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 클라이언트로부터 Facebook uid 와 access_token 을 전송 받았다고 가정하겠습니다.
public void Example(string fb_uid, string fb_access_token)
{
  string auth_key =
      Authentication.MakeFacebookAuthKey (fb_access_token);

  // 아래는 인증 요청 정보를 만드는 것입니다.
  // 첫번째 인자는 인증 플랫폼 종류를 뜻합니다.
  Authentication.AccountAuthRequest req =
      new Authentication.AccountAuthRequest (
          "Facebook", fb_uid, auth_key);
  Authentication.AccountAuthResponse rep;

  if (!Authentication.AuthenticateSync (req, out rep))
  {
    Log.Error ("authentication system error");
    return;
  }

  if (!rep.Success)
  {
    Log.Info ("login failed. code({0}), description({1})",
              rep.ReasonCode, rep.ReasonDescription);
    return;
  }

  Log.Info ("login success");
}
20.2.1.1.2. Asynchronous approach

Use Authenticate() as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void OnLogin(
    const string &fb_uid,
    const AccountAuthenticationRequest &request,
    const AccountAuthenticationResponse &response,
    const bool &error) {
  // 인증 서버에서 오류가 발생한 경우입니다.
  if (error) {
    LOG(ERROR) << "authentication system error";
    return;
  }

  // 오류는 발생하지 않았지만, 인증 결과가 실패한 경우입니다.
  // 클라이언트가 가짜로 access token 을 만들어 보내는 경우 등이 포함됩니다.
  if (not response.success) {
    LOG(INFO) << "login failed. code(" << response.reason_code << "),"
              << "description(" << response.reason_description << ")";
    return;
  }

  LOG(INFO) << "login success: " << fb_uid;
}


void example(const string &fb_uid, const string &fb_access_token) {
  AuthenticationKey auth_key = MakeFacebookAuthenticationKey(access_token);

  // 인증 종류에 상관없이 아이펀 엔진은 단일한 인증 요청 인터페이스를 이용합니다.
  // 아래는 인증 요청 정보를 만드는 것입니다.
  AccountAuthenticationRequest req("Facebook", fb_uid, auth_key);

  AuthenticationResponseHandler callback = bind(&OnLogin, fb_uid, _1, _2, _3);

  Authenticate(request, callback);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public void OnLogin(
    string fb_uid,
    Authentication.AccountAuthRequest request,
    Authentication.AccountAuthResponse response,
    bool error)
{
  if (error)
  {
    Log.Error ("authentication system error");
    return;
  }

  if (!response.Success)
  {
    Log.Info ("login failed. code({0}), description({1})",
              response.ReasonCode, response.ReasonDescription);
    return;
  }

  Log.Info ("login success");
}

public void Example(string fb_uid, string fb_access_token)
{
  string auth_key =
      Authentication.MakeFacebookAuthKey (fb_access_token);

  // 인증 종류에 상관없이 아이펀 엔진은 단일한 인증 요청 인터페이스를 이용합니다.
  // 아래는 인증 요청 정보를 만드는 것입니다.
  Authentication.AccountAuthRequest req = new
      Authentication.AccountAuthRequest ("Facebook", fb_uid, auth_key);

  Authentication.Authenticate (
      req,
      (Authentication.AccountAuthRequest request,
       Authentication.AccountAuthResponse response,
       bool error) => {
    OnLogin(fb_uid, request, response, error);
  });

  // 아니면 아래처럼 delegate를 이용하여 콜백 핸들러를 등록할 수도 있습니다.
  // Authentication.AuthResponseHandler handler = (
  //     Authentication.AccountAuthRequest request,
  //     Authentication.AccountAuthResponse response,
  //     bool error) =>
  // {
  //   ...
  // };
  // Authentication.Authenticate (req, handler);
}

20.2.2. How to use REST API

You can request REST API directly from iFun Authenticator without using iFun Engine. All parameters below are in JSON format and can be put in the HTTP POST body for requests.

20.2.2.1. Test authentication

All IDs are successfully authenticated in test authentication.

POST /v1/authentication/test
Request JSON Object:
 
  • player_id (string) – player_id
Response JSON Object:
 
  • result (integer) –
    • 0: Authentication succeeded
    • 1: Authentication failed
    • 2: Parameter error
    • Other: Other error
  • description (string) – Error details

20.2.2.2. Facebook platform authentication

POST /v1/authentication/facebook
Request JSON Object:
 
  • player_id (string) – Facebook uid
  • access_token (string) – Facebook access token
Response JSON Object:
 
  • result (integer) –
    • 0: Authentication succeeded
    • 1: Authentication failed
    • 2: Parameter error
    • Other: Other error
  • description (string) – Error details
20.2.2.2.1. Example: Facebook authentication
$ curl -X POST --data '{"player_id": "123...456", "access_token": "CAAC....tDZD"}' \
       http://localhost:12801/v1/authentication/facebook
{"result": 0, "description": ""}

20.2.2.3. IP authentication

POST /v1/authentication/ipaddress
Request JSON Object:
 
  • player_id (string) – Any ID will be successfully authenticated.
  • ip (string) – IP address
Response JSON Object:
 
  • result (integer) –
    • 0: Authentication succeeded
    • 1: Authentication failed
    • 2: Parameter error
    • Other: Other error
  • description (string) – Error details

20.3. Retrieving friends lists

You can use the function provided by iFun Engine (in this case, communication is through TCP) or independently use RESTful API.

20.3.1. Invoking the iFun Engine function

iFun Engine uses a single friends list request interface regardless of platform. Both asynchronous and synchronous functions are applied.

void fun::GetPersonalInfo(const AccountPersonalInfoRequest &request,
                          const PersonalInfoResponseHandler &handler)

bool fun::GetPersonalInfoSync(const AccountPersonalInfoRequest &request,
                              AccountPersonalInfoResponse *response)

Only the AccountPersonalInfoRequest creation method differs for each platform type. The following utility functions are provided for each platform for this purpose.

AuthenticationKey MakeFacebookAuthenticationKey(const string &facebook_access_token)

AuthenticationKey MakeGooglePlusAuthenticationKey(const string &google_client_id,
                                                  const string &google_access_token)

AuthenticationKey MakeNexonToyAuthenticationKey(int64_t svc_id,
                                                const string &client_id,
                                                const string &np_sn,
                                                const string &np_token)

Tip

See API documentation for more details.

20.3.1.1. Example: Retrieving Facebook friends

20.3.1.1.1. Synchronous approach

Use GetPersonInfoSync() as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void example(const string &fb_uid, const string &fb_access_token) {
  AuthenticationKey auth_key = MakeFacebookAuthenticationKey(access_token);

  // 사용자 정보 요청 메시지를 만듭니다.
  // 첫번째 인자는 외부 인증 종류를 의미합니다.
  AccountPersonalInfoRequest req("Facebook", fb_uid, auth_key);
  AccountPersonalInfoResponse rep;

  if (not GetPersonalInfoSync(req, &rep)) {
    LOG(ERROR) << "authentication system error";
    return;
  }

  // 오류는 발생하지 않았지만, 요청이 실패한 경우입니다.
  // 클라이언트가 가짜로 access token 을 만들어 보내는 경우 등이 포함됩니다.
  if (not rep.success) {
    LOG(INFO) << "request failed. code(" << rep.reason_code << "),"
              << "description(" << rep.reason_description << ")";
    return;
  }

  for (int i = 0; i < rep.friends.size(); ++i) {
    LOG(INFO) << "friend : " << rep.friends[i].id();
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void Example(string fb_uid, string fb_access_token)
{
  string auth_key =
      Authentication.MakeFacebookAuthKey (fb_access_token);

  // 사용자 정보 요청 메시지를 만듭니다.
  // 첫번째 인자는 외부 인증 종류를 의미합니다.
  Authentication.AccountPersonalInfoRequest req =
      new Authentication.AccountPersonalInfoRequest (
          "Facebook", fb_uid, auth_key);

  Authentication.AccountPersonalInfoResponse rep;

  if (!Authentication.GetPersonalInfoSync(req, out rep))
  {
    Log.Error ("authentication system error");
    return;
  }

  // 오류는 발생하지 않았지만, 요청이 실패한 경우입니다.
  // 클라이언트가 가짜로 access token 을 만들어 보내는 경우 등이 포함됩니다.
  if (!rep.Success) {
    Log.Info ("login failed. code({0}), description({1})",
              rep.ReasonCode, rep.ReasonDescription);
    return;
  }

  foreach (PlayerAccount account in rep.Friends)
  {
    Log.Info (account.Id);
  }
}
20.3.1.1.2. Synchronous approach

In the example above, GetPersonInfo() is used instead of GetPersonInfoSync().

20.3.2. How to use REST API

You can request REST API directly from iFun Authenticator without using iFun Engine. All parameters below are in JSON format and can be put in the HTTP POST body for requests.

20.3.2.1. Test authentication

POST /v1/personalinfo/test
Request JSON Object:
 
  • player_id (string) – Any ID will be successfully authenticated in ID and test authentication.
Response JSON Object:
 
  • result (integer) –
    • 0: Succeeded
    • 1: Authentication failed
    • 2: Parameter error
    • Other: Other error
  • description (string) – Error details
  • friends (string[]) – Friends list

20.3.2.2. Facebook platform

POST /v1/personalinfo/facebook
Request JSON Object:
 
  • player_id (string) – Facebook uid
  • access_token (string) – Facebook access token
Response JSON Object:
 
  • result (integer) –
    • 0: Succeeded
    • 1: Authentication failed
    • 2: Parameter error
    • Other: Other error
  • description (string) – Error details
  • friends (string[]) – Friends list
20.3.2.2.1. Example: Getting Facebook friends lists
$ curl -X POST --data '{"player_id": "123...456", "access_token": "CAAC....tDZD"}' \
       http://localhost:12801/v1/personalinfo/facebook
{"result": 0, "description": "", "friends": ["xx...x", "xx...x", ...,"xx...x"]}

20.4. Game server-side authentication parameters

Note

These parameters are iFun Engine game server values using iFun Authenticator. Please see Setting up iFun Authenticator (MANIFEST.json) for parameters for iFun Authenticator itself.

  • use_authenticator: Enables communication with iFun Authenticator agent. If false, all verification is bypassed and authentication is considered successful. (type=bool, default=false)
  • remote_authenticator_ip_address: IP address for remote host using iFun Authenticator. (type=string, default=”0.0.0.0”)
  • remote_authenticator_port: Port number for remote host using iFun Authenticator. (type=uint64, default=0)