Skip to content

Authorization

Balancy's authentication methods are subject to updates to enhance versatility and, for certain platforms, processes may be automated for convenience.

Understanding Authentication

Balancy initializes with automatic user authentication via the device's unique ID, associating it with a guest account. This mechanism ensures persistent user progress, even across reinstallations, provided the device ID remains consistent.

Users have the option for further authentication methods, such as email or social media platforms, typically managed through FireBase. Post-authentication, these accounts can synchronize with Balancy using Balancy.Auth.WithName.

Authentication Scenarios:

  1. Switching Accounts: To transition between Balancy accounts, follow these steps:

    1. Sign out from the current Balancy session.
    2. Utilize Balancy.Auth.WithName for re-authentication.
  2. Linking New Authentication Method: Invoking Balancy.Auth.WithName can link a new authentication method. However, outcomes vary:

    1. Should Balancy recognize it as a new authentication, the link is immediate.
    2. If another user is already linked to this authentication, a conflict arises. You must then choose between the local profile or the one on Balancy's servers. Selection dictates whether the new method replaces the current link or if the local account updates to match the server's data.

An example of the flow if the same account is playing on two devices:

  1. The new device creates a new account
  2. When you do Balancy.Auth.WithName (non existing account), the auth method is connected to the existing account
  3. If you launch the game on a new deviceID, the second account is created
  4. If you try to authenticate with the same name as in step 2 (account already exists), the conflict appears OnSystemProfileConflictAppeared.
    1. If you choose Local, the Balancy.Auth.WithName connects to the second deviceID and disconnects from the previous user.
    2. If you choose Cloud, this deviceID connects to the first account and disconnects from the second account (the second account will be lost, if there is no other authentication). The game is reloaded with the first account and OnSmartObjectsInitialized is invoked.

Authorization Methods:

Name and Password

Balancy.Auth.WithName(<username>, <password>, authResponse =>
{
    Debug.Log("Authorized " + authResponse.Success);
    if (authResponse.Success)
        Debug.Log("User id: " + authResponse.UserId);
});

As a Guest using the Device ID

Balancy.Auth.AsGuest(authResponse =>
{
    Debug.Log("Authorized " + authResponse.Success);
    if (authResponse.Success)
        Debug.Log("User id: " + authResponse.UserId);
});

Additional Methods

var balancyUserId = Balancy.Auth.GetUserId();
var isAuthorized = Balancy.Auth.IsAuthorized();

Balancy.Auth.SignOut(<game_id>, <environment>, () => {
    Debug.Log("Signed Out");
});

Server-to-Server Authentication:

Step 1: Prepare the Data

First, prepare the JSON data that will be sent to the Balancy server. This data should include the user ID, device ID, game ID, and any other required parameters for authentication:

{
  "custom_user_id": "<…>",
  "device_id": "<…>",
  "game_id": "<…>",
  "env": 1
}

where env is: Development = 0, Stage = 1, Production = 2

Step 2: Generate a Timestamp

Create a timestamp that represents the current time in milliseconds since January 1, 1970 (Unix time). In most programming languages, this can be done as follows:

timestamp = current_time_in_milliseconds

Step 3: Generate a Nonce

A Nonce is a random string added to the request to protect against replay attacks. The generation might look like this:

nonce = random_string_of_32_characters

Step 4: Create the Payload

Create a payload string by concatenating the following elements, each separated by a newline character (\n):

payload = timestamp + "\n" + nonce + "\n" + JSON_data + "\n"

This string will be used to generate the signature.

Step 5: Create the HMAC Signature

Use the HMAC algorithm with the SHA-256 hash function and your secret key to generate a signature:

signature = HMAC_SHA256(<private_key>, payload)

Here, private_key is the private key of your game used for encryption.

Step 6: Construct the HTTP Request

Create an HTTP POST request to the target URL. Include the following headers:

  • Balancy-Signature: The signature generated in the previous step.
  • Balancy-Timestamp: The timestamp as a string.
  • Balancy-Nonce: The generated nonce.
  • Content-Type: application/json to indicate that the body of the request contains JSON data.
  • X-Forwarded-For: The player's IP address to convey the origin of the request.

Example request structure:

POST /v2/auth/server HTTP/1.1
Host: api-1.api.balancy.dev
Balancy-Signature: <generated_signature>
Balancy-Timestamp: <timestamp>
Balancy-Nonce: <nonce>
Content-Type: application/json
X-Forwarded-For: <player's IP address>

{
  "custom_user_id": "myuseridstring3",
  "device_id": "mydeviceidstring3",
  "game_id": "a5a45a18-ff9b-11ec-b9e6-a185dd7463b1",
  "env": 1
}

Step 7: Handle the Response

Once the request is sent, the server will return a response in JSON format. An example of the expected response:

{
  "userId": "b3da78c0-6091-11ef-adc7-431ca20127b4",
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Il9pZCI6NzMsImRhdGUiOjE3MjQ2NzM5NTIxNDh9LCJnYW1lIjp7Il9pZCI6NDMsImJpbmRUeXBlIjo4LCJ1c2VyVmFsdWUiOiJteXVzZXJpZHN0cmluZzMifSwiaWF0IjoxNzI0NjczOTUyLCJleHAiOjE3MjcyNjU5NTJ9.YtveCuX-rBNndNYzJKbzxI7-zV_xQ-j0tLcH7S-97ng",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Il9pZCI6NzMsImRhdGUiOjE3MjQ2NzM5NTIxNDh9LCJnYW1lIjp7Il9pZCI6NDMsImJpbmRUeXBlIjo4LCJ1c2VyVmFsdWUiOiJteXVzZXJpZHN0cmluZzMifSwiaWF0IjoxNzI0NjczOTUyLCJleHAiOjE3Mjk4NTc5NTJ9.VbnSOB-U9VQoO0eOqj5CfGvCbs-N3f4eXBU5LyGRaGs",
  "status": 3,
  "country": "US",
  "time": 1724673952152
}

This response includes the user ID, access token, refresh token, status, country, and a timestamp. Process this data according to your application's business logic.

Step 8: Client-Side Integration with Balancy

When initializing Balancy with Balancy.Main.Init, it's crucial to set AutoLogin = false to prevent automatic authentication. Instead, use the OnReadyCallback to authenticate using the userId and token received from the server:

Balancy.Main.Init(new AppConfig
{
    ...
    AutoLogin = false,
    OnReadyCallback = response =>
    {
        // Perform additional actions after initialization.
        Balancy.Auth.External(<user_id>, <token>, <country_code>, <server_time_ms>);
    }
});

Note that country_code and server_time are optional parameters, but it is highly recommended to include them to enhance the accuracy of your game's data management and analytics.