Authentication Service¶
Supporting multiple authentication platforms is a very daunting task for gamer server developers. iFun Engine provides server-side authentication for major platforms and features to retrieve friend lists and nicknames. Authenticating a user with external platforms such as Facebook requires a two-step implementation for the client-side and the server-side. Most external platforms provide client-side authentication, but not server-side user authentication. Thus, the game client must authenticate with the provided SDK of the platform and receive an authentication token from the authentication server, and send the token to the game server, which must validate the received token. The server-side implementation of authentication may become a burden for the game developer as the number of supported platforms increase. iFun Engine simplifies authentication and provides it as a service.
iFun Engine-Authenticator Agent¶
This agent is fully in charge of authentication in iFun Engine. When a iFun Engine game requires authentication, it sends an authentication request to this agent. The iFun Engine-authenticator agent supports the following external authentication platforms. (We plan to continuously increase the number of supported external platforms.)
Facebook
Twitter
Installation¶
When developing a game server with iFun Engine, you can set
use_authenticator
to false
as explained here
to work in test mode. You can install later if you are evaluating or in the early stages of
development and don’t need real authentication.
Install the iFun Engine auto-configuration package as explained here and install with the following commands.
$ sudo apt-get update
$ sudo apt-get install funapi-authenticator1
Modify to enabled=1
in the file opened with the following command.
$ sudo vim /usr/share/funapi-authenticator/manifests/src/MANIFEST.json
Start the service with the following command.
(The log is created in /var/log/funapi/funapi-authenticator1/
)
$ sudo service funapi-authenticator1 start
Configuration¶
Open the configuration file as below and modify the appropriate values.
$ sudo vim /usr/share/funapi-authenticator/manifests/src/MANIFEST.json
Usage¶
You can either use the provided iFun Engine API (if developing the game server with iFun Engine) or the independent HTTP Interface (RESTful API). Refer to the following sections.
MANIFEST.json Configuration¶
To use the iFun Engine server-side authentication service, you need to start the funapi-authenticator agent, and configure the iFun Engine game to use this agent. See the MANIFEST.json section and the description below to configure authentication.
Component name: AuthenticationClient
Arguments
use_authenticator
: Set astrue
orfalse
. If set asfalse
, funapi-authenticator will bypass authentication and deem all authentication requests as successful. This is useful for the developer to bypass authentication and test the game in a local environment.remote_authenticator_ip_address
: Set the IP address of funapi-authenticator. The default value is used if not set.remote_authenticator_port
: Set the port of iFun Engine-Authenticator. The default value is used if not set.
Usage Example¶
We’ll see how authentication works in iFun Engine games through an example. The following example is for Facebook authentication. For authentication with Facebook, the game client connects to the Facebook authentication server, inputs the Facebook ID and password, and receives an “access token”. When the game client sends the access token to the game server, the server can validate the access token in the following maner.
Facebook: Synchronous method to validate client authentication¶
To validate authentication at the server with the synchronous method,
call the function AuthenticateSync()
as below.
#include <funapi.h>
using namespace fun;
// Assume we receive the Facebook uid and access_token from the client.
void example(const string &fb_uid, const string &fb_access_token) {
// With Facebook, you can get the authentication key from the access token.
// Use the iFun Engine utility function MakeFacebookAuthencationKey.
AuthenticationKey auth_key = MakeFacebookAuthenticationKey(access_token);
// iFun Engine provides a single authentication request interface regardless
// of authentication type.
// Below is to create an account authentication request.
// The first argument is the type of the authentication platform.
AccountAuthenticationRequest req("Facebook", fb_uid, auth_key);
// The variable to receive the authentication response.
AccountAuthenticationResponse rep;
// Call the synchronous version of the function.
if (not AuthenticateSync(req, &rep)) {
// Error case.
LOG(ERROR) << "authentication system error";
return;
}
// Not an error, but failed authentication.
// This includes cases where the client sends a fake access token.
if (not rep.success) {
// login failure
LOG(INFO) << "login failed. code(" << rep.reason_code << "),"
<< "description(" << rep.reason_description << ")";
return;
}
// Authentication succeeded.
LOG(INFO) << "login success";
}
using funapi;
// Assume we receive the Facebook uid and access_token from the client.
public void example(string fb_uid, string fb_access_token)
{
// With Facebook, you can get the authentication key from the access token.
// Use the iFun Engine utility function MakeFacebookAuthencationKey.
string auth_key =
Authentication.MakeFacebookAuthKey (fb_access_token);
// iFun Engine provides a single authentication request interface regardless
// of authentication type.
// Below is to create an account authentication request.
// The first argument is the type of the authentication platform.
Authentication.AccountAuthRequest req =
new Authentication.AccountAuthRequest (
"Facebook", fb_uid, auth_key);
// The variable to receive the authentication response.
Authentication.AccountAuthResponse rep;
// Call the synchronous version of the function.
if (!Authentication.AuthenticateSync (req, out rep))
{
// Error case.
Log.Error ("authentication system error");
return;
}
// Not an error, but failed authentication.
// This includes cases where the client sends a fake access token.
if (!rep.Success)
{
Log.Info ("login failed. code({0}), description({1})",
rep.ReasonCode, rep.ReasonDescription);
return;
}
// Authentication succeeded.
Log.Info ("login success");
}
Facebook: Asynchronous method to validate client authentication¶
Developers who prefer asynchronous calls can use Authenticate()
instead of AuthenticateSync()
as below.
#include <funapi.h>
using namespace fun;
// In the asynchronous method, iFun Engine calls the registered callback
// function when the result is ready.
// Define the callback function.
void OnLogin(
const string &fb_uid,
const AccountAuthenticationRequest &request,
const AccountAuthenticationResponse &response,
const bool &error) {
// This is an error at the authentication server.
if (error) {
// system error
LOG(ERROR) << "authentication system error";
return;
}
// Not an error, but failed authentication.
// This includes cases where the client sends a fake access token.
if (not response.success) {
// login failure
LOG(INFO) << "login failed. code(" << response.reason_code << "),"
<< "description(" << response.reason_description << ")";
return;
}
// Authentication succeeded.
LOG(INFO) << "login success: " << fb_uid;
}
// Assume we receive the Facebook uid and access_token from the client.
void example(const string &fb_uid, const string &fb_access_token) {
// With Facebook, you can get the authentication key from the access token.
// Use the iFun Engine utility function MakeFacebookAuthencationKey as in the
// synchronized version.
AuthenticationKey auth_key = MakeFacebookAuthenticationKey(access_token);
// iFun Engine provides a single authentication request interface regardless
// of authentication type.
// Below is to create an account authentication request.
AccountAuthenticationRequest req("Facebook", fb_uid, auth_key);
// Define the callback function to be called when the authentication result is ready.
// Create a functor with bind().
AuthenticationResponseHandler callback = bind(&OnLogin, fb_uid, _1, _2, _3);
// Request authentication validation with the asynchronous method. Send the authentication request and callback function as arguments.
Authenticate(request, callback);
}
using funapi;
// In the asynchronous method, iFun Engine calls the registered callback
// function when the result is ready.
// Define the callback function.
public void OnLogin(
string fb_uid,
Authentication.AccountAuthRequest request,
Authentication.AccountAuthResponse response,
bool error)
{
if (error)
{
// system error
Log.Error ("authentication system error");
return;
}
if (!response.Success)
{
// Not an error, but failed authentication.
// This includes cases where the client sends a fake access token.
Log.Info ("login failed. code({0}), description({1})",
response.ReasonCode, response.ReasonDescription);
return;
}
// Authentication succeeded.
Log.Info ("login success");
}
// Assume we receive the Facebook uid and access_token from the client.
public void example(string fb_uid, string fb_access_token)
{
// With Facebook, you can get the authentication key from the access token.
// Use the iFun Engine utility function MakeFacebookAuthencationKey as in the
// synchronized version.
string auth_key =
Authentication.MakeFacebookAuthKey (fb_access_token);
// iFun Engine provides a single authentication request interface regardless
// of authentication type.
// Below is to create an account authentication request.
Authentication.AccountAuthRequest req = new
Authentication.AccountAuthRequest ("Facebook", fb_uid, auth_key);
// Request authentication validation with the asynchronous method. Send the authentication request and callback lambda function as arguments.
Authentication.Authenticate (
req,
(Authentication.AccountAuthRequest request,
Authentication.AccountAuthResponse response,
bool error) => {
OnLogin(fb_uid, request, response, error);
});
}
Facebook: Synchronous method to retrieve the friend list¶
Now, let’s retrieve the friend list. The example below uses the
synchronous method. The asynchronous method is similar, but call
GetPersonalInfo()
instead of GetPersonalInfoSync()
.
#include <funapi.h>
using namespace fun;
// Assume we receive the Facebook uid and access_token from the client.
void example(const string &fb_uid, const string &fb_access_token) {
// With Facebook, you can get the authentication key from the access token.
// Use the iFun Engine utility function MakeFacebookAuthencationKey.
AuthenticationKey auth_key = MakeFacebookAuthenticationKey(access_token);
// Create the personal info request message.
// The first argument is the type of the authentication platform.
AccountPersonalInfoRequest req("Facebook", fb_uid, auth_key);
AccountPersonalInfoResponse rep;
// Retrieve personal info with the synchronous method.
if (not GetPersonalInfoSync(req, &rep)) {
// A system error has occurred.
LOG(ERROR) << "authentication system error";
return;
}
// Not an error, but failed authentication.
// This includes cases where the client sends a fake access token.
if (not rep.success) {
// login failure
LOG(INFO) << "request failed. code(" << rep.reason_code << "),"
<< "description(" << rep.reason_description << ")";
return;
}
// The request was successful.
for (int i = 0; i < rep.friends.size(); ++i) {
LOG(INFO) << "friend : " << rep.friends[i].id();
}
}
using funapi;
// Assume we receive the Facebook uid and access_token from the client.
public void example(string fb_uid, string fb_access_token)
{
// With Facebook, you can get the authentication key from the access token.
// Use the iFun Engine utility function MakeFacebookAuthencationKey.
string auth_key =
Authentication.MakeFacebookAuthKey (fb_access_token);
// Create the personal info request message.
// The first argument is the type of the authentication platform.
Authentication.AccountPersonalInfoRequest req =
new Authentication.AccountPersonalInfoRequest (
"Facebook", fb_uid, auth_key);
Authentication.AccountPersonalInfoResponse rep;
// Retrieve personal info with the synchronous method.
if (!Authentication.GetPersonalInfoSync(req, out rep))
{
// A system error has occurred.
Log.Error ("authentication system error");
return;
}
// Not an error, but failed authentication.
// This includes cases where the client sends a fake access token.
if (!rep.Success) {
// login failure
Log.Info ("login failed. code({0}), description({1})",
rep.ReasonCode, rep.ReasonDescription);
return;
}
// The request was successful.
foreach (PlayerAccount account in rep.Friends)
{
Log.Info (account.Id);
}
}
iFun Engine-Authenticator HTTP Interface¶
You can use the funapi-authenticator agent independently, without using the iFun Engine API. As specified below, you can set each parameter in JSON format in the body of an HTTP post request and send it to the funapi-authenticator.
Test authentication
-
POST
/v1/authentication/test
¶ - Request JSON Object
player_id (string) – player_id. all id value will be authenticated
- Response JSON Object
result (integer) –
0
: authentication success1
: authentication failure2
: incorrect parametersother: other errors
description (string) – error description
Facebook 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 success1
: authentication failure2
: incorrect parametersother: other errors
description (string) – error description
IP authentication
-
POST
/v1/authentication/ipaddress
¶ - Request JSON Object
player_id (string) – All id value will be authenticated
ip (string) – IP address
- Response JSON Object
result (integer) –
0
: authentication success1
: authentication failure2
: incorrect parametersother: other errors
Example - Facebook Authentication¶
$ telnet localhost 12801
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
POST /v1/authentication/facebook HTTP/1.1
Content-Length: xx
{"player_id": "123...456", "access_token": "CAACEdEose0cBANPFe..........tIyVFo09wZDZD"}
HTTP/1.1 200 OK
content-length: 32
content-type: application/json
{"result": 0, "description": ""}
Test friend list retrieval
-
POST
/v1/personalinfo/test
¶ - Request JSON Object
player_id (string) – player id, in test authentication, any id value is successful
- Response JSON Object
result (integer) –
0
: success1
: authentication failure2
: incorrect parametersother: other errors
description (string) – error description
friends (string[]) – friend list
Facebook friend list retrieval
-
POST
/v1/personalinfo/facebook
¶ - Request JSON Object
player_id (string) – Facebook uid
access_token (string) – Facebook access token
- Response JSON Object
result (integer) –
0
: success1
: authentication failure2
: incorrect parametersother: other errors
description (string) – error description
friends (string[]) – friend list
Example - Facebook friend list retrieval¶
$ telnet localhost 12801
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
POST /v1/personalinfo/facebook HTTP/1.1
Content-Length: xx
{"player_id": "123...456", "access_token": "CAACEdEose0cBANPFe..........tIyVFo09wZDZD"}
HTTP/1.1 200 OK
content-length: 32
content-type: application/json
{"result": 0, "description": "", "friends": ["xx...x", "xx...x", ...,"xx...x"]}