Create a username account
To create a username account, use Username, Password, ClientId, PKCE, and DeviceKey. If you apply additional security, also use GrantKey.
1. Prepare the call parameters
Prepare the parameters required to create a username account.
Username
Username is the login identifier used to create the account. After you receive user input according to your app's policy, you must check the format rules.
- Usernames do not enforce a specific ID format, and you can set up the login ID scheme according to your app's policy.
- Usernames allow uppercase and lowercase English letters, numbers, and some special characters (
._-), must contain at least one English letter, and must be 3 to 20 characters long.
Password
For Password, pass the 64-digit hexadecimal string of SHA256(raw_password), not the original password. The SDK does not perform hashing, so the app must generate it itself.
using System.Security.Cryptography;
using System.Text;
// Do not send the password in plain text; convert it to the hexadecimal string of SHA256(raw) and pass that.
static string Sha256Hex(string raw)
{
using var sha = SHA256.Create();
byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes(raw));
var sb = new StringBuilder(hash.Length * 2);
foreach (byte b in hash) sb.Append(b.ToString("x2"));
return sb.ToString();
}
ClientId
This is the Client ID that the Hive Console issues per project. All App IDs in the same project use the same value. Check the value in Get the security key.
PKCE: codeChallenge and codeVerifier
PKCE (codeVerifier and codeChallenge) is a pair of one-time values that protects the issued authorization code from being misused even if it is intercepted in transit. The app must generate them itself.
using System;
using System.Security.Cryptography;
using System.Text;
// PKCE(RFC 7636): generate codeVerifier + codeChallenge = BASE64URL(SHA256(codeVerifier))
static (string verifier, string challenge) CreatePkce()
{
var bytes = new byte[32];
using (var rng = RandomNumberGenerator.Create()) rng.GetBytes(bytes);
string verifier = Base64Url(bytes);
using var sha = SHA256.Create();
string challenge = Base64Url(sha.ComputeHash(Encoding.ASCII.GetBytes(verifier)));
return (verifier, challenge);
}
static string Base64Url(byte[] b) =>
Convert.ToBase64String(b).TrimEnd('=').Replace('+', '-').Replace('/', '_');
DeviceKey
DeviceKey is a device identification value that distinguishes login sessions by device. The Hive Axyl authentication server does not issue or interpret this value, so the app must create and pass it itself.
Server validation conditions
The Hive Axyl authentication server validates only the length and characters of DeviceKey. If you send a value that does not meet the conditions, the account creation request fails. For failure handling, see Common error handling.
- Length: 22 to 64 characters
- Characters: Only ASCII characters excluding spaces and control characters are allowed; Korean characters and emoji are not allowed
- Format: Not validated
Conditions the app must meet
The server does not check whether this value actually corresponds to one device, so the app itself must meet the following conditions.
- A different value for each device. A random value such as a UUID is recommended
- A value that is saved on the device and reused continuously
When the conditions are not met
If you create a new value for every call, the server recognizes the same device as a different device each time. Conversely, if you put a fixed value in the app code, every device of every user of that app sends the same value. Even a fixed value passes server validation as long as it meets the validation conditions above.
In an app with a fixed value, if one user logs in on two devices, the server treats them as the same device. The device that logs in later overwrites the login session of the earlier device, so the user must log in again every time they switch between devices. Logging out on one device also ends the login on the other device. Because the server returns no error, this symptom surfaces only after user inquiries pile up.
Creation example
The app decides the format. You can use any scheme you want, such as UUID, a hexadecimal string, or base64, and UUID v4 is recommended. The example below creates a 32-character string by removing the hyphens from a UUID v4.
Note
You must pass the same DeviceKey created here in later login requests sent from this device.
2. Create a username account
CreateUsernameAsync
Call CreateUsernameAsync() to create a username account.
Call parameters
| Field name | Type | Required | Description |
|---|---|---|---|
| request | UsernameCreateRequest | Required | Username account creation request |
| context | ApiCallContext | Optional | Per-call settings object. If omitted, the default values are used. |
UsernameCreateRequest
| Field name | Type | Required | Description |
|---|---|---|---|
Username | string | Required | Username to use |
Password | string | Required | The SHA256(raw_password) value of the password. It is a 64-digit hexadecimal value, and you cannot pass plain text. |
ClientId | string | Required | Client ID of the console security key issued per project |
CodeChallenge | string | Required | PKCE code challenge (SHA256 hash of codeVerifier) |
CodeChallengeMethod | CodeChallengeMethod | Required | PKCE method. S256 |
DeviceKey | string | Required | Device identification value that distinguishes login sessions by device. 22 to 64 characters |
GrantKey | string | Optional | The grant key that the app server obtained and passed. Required for apps with additional security turned on. You can send it even when additional security is off, and a sent value is always validated and consumed regardless of the setting. See Apply additional security. |
Call example
For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
using Hive.Axyl.Auth;
using Hive.Axyl.Core;
using UnityEngine;
IAuthService auth = HiveCore.Resolve<IAuthService>();
var (codeVerifier, codeChallenge) = CreatePkce();
// Create a new value only on first launch. Save the created value on the device and reuse it in later requests.
string deviceKey = NewDeviceKey();
var result = await auth.CreateUsernameAsync(new UsernameCreateRequest {
Username = inputUsername,
Password = Sha256Hex(rawPassword), // No plain text: pass the SHA256 hash
ClientId = "{clientId}",
CodeChallenge = codeChallenge,
CodeChallengeMethod = CodeChallengeMethod.S256,
DeviceKey = deviceKey,
// GrantKey: We recommend passing the grant key issued to the app server, in case you turn on additional security.
});
switch (result)
{
case AuthCreateUsernameResult.Success success:
long playerId = success.Data.PlayerId;
string authorizationCode = success.Data.AuthorizationCode;
// The authorizationCode in this step is the response value for the account creation request.
// You can refer to playerId and deviceKey again later in the app flow.
break;
case AuthCreateUsernameResult.UsernameAlreadyExists:
// The username is already in use. Prompt the user to enter a different value.
break;
// Handle common failures (network and server errors)
case AuthCreateUsernameResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// Safety net: unhandled results and unknown new results (UnknownOutcome)
default:
Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
break;
}
Response data
On success, the result is contained in Data (UsernameCreateResponseData) of AuthCreateUsernameResult.Success. Unlike a guest account, GuestToken is not returned.
| Field name | Type | Required | Description |
|---|---|---|---|
Data.PlayerId | long | Required | Player ID that identifies the newly created account |
Data.AuthorizationCode | string | Required | Authorization code used to issue access tokens and refresh tokens |
Data.CreatedAt | DateTimeOffset | Required | Creation time (UTC) |
Note
Data.AuthorizationCode is an authorization code used to issue access tokens and refresh tokens. However, this code is not used in the login process. You get a new authorization code required for login later, in the Log in step.
Response example
Response status
We recommend handling the response cases of AuthCreateUsernameResult with a switch statement.
| Response case | Description | App client handling |
|---|---|---|
Success | Username account creation succeeded. Data contains PlayerId, AuthorizationCode, and so on. | Check the account creation result, and then proceed to the login step |
UsernameAlreadyExists | The username is already in use | Prompt the user to enter a different username |
InvalidClientId | The Client ID is invalid | Check the console security key |
InvalidGrantKey | The grant key sent in GrantKey is invalid or expired | Get a new grant key from the app server and retry. See Apply additional security |
GrantRequiredMissing | The additional security (grant key) setting is enabled, but GrantKey is missing | Check the Apply additional security settings |
IpBlocked | The access IP is blocked | Inform the user of the policy |
ProviderConfigNotFound | No login method (provider configuration) is set for the app | Check the console login settings |
AppNotFound | The app information cannot be found | Check the app registration status in the console |
TerminateService | The app's service has ended | Check the service operation status |
UnknownOutcome | A new result unknown to this SDK version | Log it and handle it conservatively |
Failure | Common Failure. Missing or malformed required parameters (invalid_parameter), missing required fields (missing_field), and a missing X-App-Id header (missing_app_id) also fall into this case. The cause is contained in Failure.Problem.ExternalCode. See Common error handling. | Handle according to the common error handling criteria |
Next steps
To log in with the account you created, see Log in.
Note
Creating an account alone does not create a login session. The login session is created in the Log in step.