21. Deprecated - iFun Authenticator¶
Attention
인증 에이전트에서 제공하는 기능들이 엔진 자체 기능으로 통합됨에 따라 아이펀 인증 에이전트 (iFun Authenticator) 프로그램은 더 이상 지원하지 않으며(Deprecated) 제거될 예정 입니다. 엔진에서 제공하는 인증 기능은 외부 서비스 지원 Part 1: 인증 검증 문서를 참고해주시기 바랍니다.
若使用Facebook、Google Plus等外部平台,为了执行用户验证,需要实现Client-side、erver-side两个阶段的认证。 在游戏客户端上运用相应平台的SDK进行验证,将可以识别认证事实的密钥传输给游戏服务器后,在游戏服务器上进行密钥的有效性检验。
大部分平台仅提供客户端认证,不提供服务器端的认证。 因此,联动的平台数量越多,给服务器开发商造成的负担越大。 iFun引擎提供了与主要平台之间的Server-side认证功能,以及导入好友列表、昵称等功能。
21.1. iFun Authenticator¶
iFun引擎使用名为 iFun Authenticator 的程序,作为专门负责认证的agent。 游戏服务器向iFun Authenticator发送认证验证请求,iFun Authenticator对不同平台进行验证。
Note
iFun引擎使用单独的认证agent是为了不影响游戏服务器,以便能够添加新的认证或更改认证。
同时,使用agent还可以使非游戏服务器的其他服务器通过agent的REST API来使用认证相关服务,因此十分便利。
21.1.2. 安装方法¶
Tip
将 游戏服务器端认证验证设置参数 的 use_authenticator
设置为 false
,游戏服务器就会以批准所有认证验证请求的测试模式运行。
该设置在无需实际认证的开发初期阶段十分有用,此时无需安装iFun Authenticator。
21.1.2.1. Ubuntu环境¶
$ sudo apt-get update
$ sudo apt-get install funapi-authenticator1
21.1.2.2. CentOS环境¶
$ sudo yum install funapi-authenticator1
21.1.3. 运行方法¶
21.1.3.1. Ubuntu 14.04或Centos 6环境下¶
打开 /etc/default/funapi-authenticator
文件,修改为 enabled=1
。
然后执行以下命令。
$ sudo service funapi-authenticator start
21.1.3.2. Ubuntu 16.04或Centos 7环境下¶
执行以下命令。
$ sudo systemctl enable funapi-authenticator
$ sudo systemctl start funapi-authenticator
21.1.4. 查看任务¶
21.1.4.1. Ubuntu 14.04或Centos 6环境下¶
$ sudo service funapi-authenticator status
21.1.4.2. Ubuntu 16.04或Centos 7环境下¶
$ sudo systemctl status funapi-authenticator
21.1.4.3. Log文件¶
在 /var/log/funapi/funapi-authenticator/
中生成日志文件。
21.1.5. iFun Authenticator设置方法(MANIFEST.json)¶
Note
该项目是iFun Authenticator自身的设置内容。使用iFun Authenticator设置游戏服务器时,请参考 游戏服务器端认证验证设置参数 。
iFun Authenticator也是通过iFun引擎编写的程序。
因此,iFun Authenticator也可以通过 MANIFEST.json
更改设置值。
iFun Authenticator的MANIFEST.json位于 /usr/share/funapi-authenticator/default/manifests/MANIFEST.json
。
可以指定如下设置值。
tcp_listen_port: 指定iFun引擎游戏服务器与iFun Authenticator通信时的TCP port编号。(type=uint16, default=12800)
http_listen_port: 指定通过REST API与iFun Authenticator通信时的HTTP port编号。(type=uint16, default=12801)
bypass: 是否无条件通过认证验证。使iFun Authenticator以测试模式运行。与在iFun引擎游戏服务器中指定为
use_authenticator=false
的效果相同。(type=bool, default=false)ip_address_table_path: 指定含有可向iFun Authenticator发送请求的服务器IP地址的数据表文件路径。须指定
/usr/share/funapi-authenticator/default/resources/
的相对路径。(type=string, default=”acl/ip_address_table”)
Tip
若更新代理,原来的MANIFEST.json将被覆盖。为了防止该问题,可以按照 临时重写MANIFEST.json 中的介绍,使用override文件。
/etc/funapi-authenticator/MANIFEST.override.json:
{
"override": {
"FunapiAuthenticatorServer": {
"tcp_listen_port": 8070,
"http_listen_port": 8080,
...
},
...
}
}
21.2. 认证验证¶
有使用iFun引擎提供的函数的方法(此时通过TCP通信),以及独立运用RESTful API的方法。
21.2.1. 在iFun引擎中调用函数的方法¶
iFun引擎使用单一的认证请求接口,与平台种类无关。 运用以下两个函数。分别是非同步、同步函数。
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
객체를 생성하기 위해서는 다음과 같은 인자가 필요합니다.
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);
|
각 인자에 대한 설명은 다음과 같습니다.
service_provider: 서비스 제공자를 지정하며 다음 인자 중 하나를 사용할 수 있습니다.
Facebook
: Facebook 서비스GooglePlus
: Google+ 서비스NexonToy
: Nexon Toy 서비스
local_account: 사용자 계정을 판별할 수 있는 고유 식별자를 입력합니다. Facebook의 경우 uuid가 고유식별자가 될 수 있습니다.
key: 인증 정보를 담는 객체입니다. 플랫폼 별로 제공되는 다음 함수를 통해 생성할 수 있습니다.
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
更具体的内容请参考 API文件 。
21.2.1.1. 示例: Facebook认证验证¶
为进行Facebook认证,游戏客户端需访问Facebook认证服务器,输入Facebook ID和 密码,获取”access token”。游戏客户端 将该access token传输给游戏服务器后,游戏服务器可通过如下方式检验access token是否有效。
21.2.1.1.1. 同步方式¶
按如下所示,使用 AuthenticateSync()
。
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");
}
|
21.2.1.1.2. 非同步方式¶
按如下所示,使用 Authenticate()
。
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);
}
|
21.2.2. 利用REST API的方法¶
可以不使用iFun引擎,直接向iFun Authenticator请求REST API。 根据如下内容,以JSON format将各个参数包含在HTTP POST的body中,进行请求即可。
21.2.2.1. Test认证¶
在Test认证中,所有id值均认证成功。
-
POST
/v1/authentication/test
¶ - Request JSON Object
player_id (string) – player_id
- Response JSON Object
result (integer) –
0
: 认证成功1
: 认证失败2
: 参数错误其他: 其他错误
description (string) – 错误说明
21.2.2.2. Facebook平台认证¶
-
POST
/v1/authentication/facebook
¶ - Request JSON Object
player_id (string) – Facebook uid
access_token (string) – Facebook access token
- Response JSON Object
result (integer) –
0
: 认证成功1
: 认证失败2
: 参数错误其他: 其他错误
description (string) – 错误说明
21.2.2.2.1. 示例: Facebook认证验证¶
$ curl -X POST --data '{"player_id": "123...456", "access_token": "CAAC....tDZD"}' \
http://localhost:12801/v1/authentication/facebook
{"result": 0, "description": ""}
21.3. 提取好友列表¶
有使用iFun引擎提供的函数的方法(此时通过TCP通信),以及独立运用RESTful API的方法。
21.3.1. 在iFun引擎中调用函数的方法¶
iFun引擎使用单一的好友列表请求接口,与平台种类无关。 运用以下两个函数。分别是非同步、同步函数。
void fun::GetPersonalInfo(const AccountPersonalInfoRequest &request,
const PersonalInfoResponseHandler &handler)
bool fun::GetPersonalInfoSync(const AccountPersonalInfoRequest &request,
AccountPersonalInfoResponse *response)
此时各个种类平台的差别只是生成 AccountPersonalInfoRequest
的方式不同。
为此,针对各个平台提供了以下Utility函数。
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
更具体的内容请参考 API文件 。
21.3.1.1. 示例: 提取Facebook好友¶
21.3.1.1.1. 同步方式¶
按如下所示,使用 GetPersonInfoSync()
。
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);
}
}
|
21.3.1.1.2. 非同步方式¶
在上述示例中,可使用 GetPersonInfo()
来代替 GetPersonInfoSync()
。
21.3.2. 利用REST API的方法¶
可以不使用iFun引擎,直接向iFun Authenticator请求REST API。 根据如下内容,以JSON format将各个参数包含在HTTP POST的body中,进行请求即可。
21.3.2.1. Test认证¶
-
POST
/v1/personalinfo/test
¶ - Request JSON Object
player_id (string) – 在id、test认证中,所有id值均认证成功。
- Response JSON Object
result (integer) –
0
: 成功1
: 认证失败2
: 参数错误其他: 其他错误
description (string) – 错误说明
friends (string[]) – 好友列表
21.3.2.2. Facebook平台¶
-
POST
/v1/personalinfo/facebook
¶ - Request JSON Object
player_id (string) – Facebook uid
access_token (string) – Facebook access token
- Response JSON Object
result (integer) –
0
: 成功1
: 认证失败2
: 参数错误其他: 其他错误
description (string) – 错误说明
friends (string[]) – 好友列表
21.3.2.2.1. 示例: 获取Facebook好友列表¶
$ 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"]}
21.4. 游戏服务器端认证验证设置参数¶
Note
该设置参数是使用iFun Authenticator的iFun引擎游戏服务器的值。iFun Authenticator自身的设置参数请参考 iFun Authenticator设置方法(MANIFEST.json) 。
use_authenticator: 是否激活与iFun Authenticator agent之间的通信。若为
false
,则bypass所有验证过程,并视为已经成功。(type=bool, default=false)remote_authenticator_ip_address: iFun Authenticator运行的远程主机IP地址。(type=string, default=”0.0.0.0”)
remote_authenticator_port: iFun Authenticator运行的远程主机的端口编号。(type=uint64, default=0)