Skip to content

Automatic login

Automatic login is a flow that lets a user who logged in before enter the app directly, without going through the login screen, when they relaunch the app. The Hive Axyl SDK keeps the session only in memory and does not save it on the device. Therefore, the app client must keep the credentials itself and restore the session on the next launch.

Automatic login is not done with a single method. The app client completes it by calling Hive Axyl SDK features in order.

flowchart TD
    A(["App launch"])
    B(["Load saved credentials"])
    C(["Request session restoration with saved tokens"])
    D(["Issue new tokens"])
    E(["Register the session and enter the app"])
    F(["Show the login screen"])

    A --> B --> C --> D --> E
    B -- No saved values --> F
    C -- Restoration failed --> F
    D -- Issuance failed --> F

Building blocks

The building blocks used for automatic login are as follows.

  • ISecureStorage: Secure storage that encrypts values needed again on the next launch, such as access tokens and refresh tokens, saves them on the device, and loads them
  • IAuthService.LoginWithAccessTokenAsync: Method that logs in while the Hive Axyl authentication server checks whether the saved access token is still valid, and returns an authorization code on success
  • ITokenService.IssueTokenAsync: Method that issues a new access token and refresh token with an authorization code or a refresh token
  • ISessionManager.SetSession: Method that registers the issued tokens in the session to put the user in a logged-in state
  • AuthTokenRefresh.Enable: Method that turns on the feature that, after the session is registered, automatically refreshes an expired access token with the refresh token

The Hive Axyl SDK provides only the building blocks above. The app client decides which values to save under which keys, and at what point during app launch to restore them.

Warning

Do not register the saved tokens in the session with SetSession() before validation is complete. If the validation call fails, it is incorrectly handled as a session expiration, and automatic refresh and session events get out of sync. Call SetSession() only once, after the entire restoration flow succeeds.

1. Save credentials

Right after login succeeds and the session is registered, save the values needed for the next launch to secure storage. The values to save are as follows.

  • Access token and refresh token
  • Player ID
  • deviceKey

deviceKey is a device identification value. Create it when the app first launches, and keep reusing it regardless of the account type. For the rules for creating and storing it, see deviceKey. For a guest account, also save guestToken, the credential for logging in again. However, the guest token becomes invalid when a login method is linked to that account for the first time, so delete the saved guest token when linking succeeds. For details, see Link accounts and get linked login methods.

using Hive.Axyl.Core;
using Hive.Axyl.Storage;

// Secure storage is not registered in unsupported environments such as the Editor, so check with TryResolve.
if (!HiveCore.TryResolve<ISecureStorage>(out var storage))
{
    return; // Credentials are not saved, so automatic login is not used on the next launch.
}
ISessionManager session = HiveCore.Resolve<ISessionManager>();

SessionSnapshot snapshot = session.GetSnapshot();

// The keys below are examples of values the app defines (the SDK does not define them). Delete them with the same keys on logout and account deletion as well.
await storage.SaveAsync(new SecureStorageSaveRequest {
    Key   = "hive.axyl.auth.access_token",
    Value = snapshot.AccessToken,
});
await storage.SaveAsync(new SecureStorageSaveRequest {
    Key   = "hive.axyl.auth.refresh_token",
    Value = snapshot.RefreshToken,
});
await storage.SaveAsync(new SecureStorageSaveRequest {
    Key   = "hive.axyl.auth.player_id",
    Value = snapshot.PlayerId.ToString(),
});

If SaveAsync() returns AccessDenied or DataCorrupted, the save has failed. In this case, automatic login does not work on the next launch, so the user must log in again.

2. Restore the session at app launch

When the app launches, attempt restoration before drawing the login screen. If there are no saved values, show the login screen right away.

2.1. Restore with the saved access token

If the saved access token is still valid, you can revive the session without authenticating the user again. When you call LoginWithAccessTokenAsync() and send the saved access token with ApiCallContext.WithAccessToken(), the Hive Axyl authentication server validates the token and returns a new authorization code.

using Hive.Axyl.Auth;
using Hive.Axyl.Core;

IAuthService auth = HiveCore.Resolve<IAuthService>();

// CreatePkce() is helper code defined in guest account creation.
var (codeVerifier, codeChallenge) = CreatePkce();

var result = await auth.LoginWithAccessTokenAsync(
    new TokenLoginRequest {
        ClientId            = "{clientId}",
        CodeChallenge       = codeChallenge,
        CodeChallengeMethod = CodeChallengeMethod.S256,
    },
    ApiCallContext.WithAccessToken(storedAccessToken));

if (result is AuthLoginWithAccessTokenResult.Success success
    && success.Data.PlayerId == storedPlayerId)
{
    // Exchange the authorization code for tokens and register them in the session.
    await StartSessionAsync(success.Data.AuthorizationCode, codeVerifier, success.Data.PlayerId);
}

If Data.PlayerId in the response differs from the saved Player ID, a session for a different account could be established. Stop immediately, do not delete the saved values, and guide the user to log in manually.

StartSessionAsync() is helper code that exchanges the authorization code for tokens and registers them in the session. For its implementation, see Activate the session.

2.2. Restore with the saved refresh token

If step 2.1 fails because the saved access token has expired, get new tokens issued with the refresh token. When you pass RefreshTokenTokenRequest to IssueTokenAsync(), tokens are issued even when there is no session.

using System;
using Hive.Axyl.Auth;
using Hive.Axyl.Core;

ITokenService token = HiveCore.Resolve<ITokenService>();
ISessionManager session = HiveCore.Resolve<ISessionManager>();

var issueResult = await token.IssueTokenAsync(new RefreshTokenTokenRequest {
    GrantType    = "refresh_token",
    ClientId     = "{clientId}",
    RefreshToken = storedRefreshToken,
});

if (issueResult is TokenIssueTokenResult.Success issued)
{
    session.SetSession(
        issued.Data.AccessToken,
        issued.Data.RefreshToken ?? string.Empty,
        storedPlayerId,
        DateTimeOffset.UtcNow.ToUnixTimeSeconds() + issued.Data.ExpiresIn);

    // Save the newly issued tokens to secure storage again.
}

Each time a refresh token is used, the Hive Axyl authentication server replaces it with a new value and invalidates the old one. Handle the saved values as follows, depending on the issuance result. For the decision criteria, see Common error handling.

  • Success: You must update the saved access token and refresh token with the new values.
  • InvalidGrantRefreshToken: The refresh token is confirmed to be invalid. Keep the guest account's guestToken and deviceKey, delete the saved access token and refresh token, and then show the login screen.
  • TemporarilyUnavailable: Do not delete the saved values. Send the same request again after an interval.
  • Failures where invalidity could not be confirmed, such as network errors: Do not delete the saved values.

2.3. Fall back to logging in again

If both paths fail, give up on automatic login and show the login screen. A guest account can log in again with the saved guestPlayerId, guestToken, and deviceKey to get back the same Player ID. For the implementation, see Log in as a guest.

3. Refresh access tokens automatically

Even after the session is registered, the access token expires after a certain amount of time. If you call AuthTokenRefresh.Enable() once, then when a method is called with an expired token, the Hive Axyl SDK gets new tokens issued with the session's refresh token, updates the session, and continues processing the original request. App usage is not interrupted, even without any separate action by the user.

3.1. Turn on automatic refresh

After initializing the SDK, call AuthTokenRefresh.Enable() once.

using Hive.Axyl.Auth;

// Call this only once after SDK initialization. baseUrl is the same value as the token server host that ITokenService uses.
AuthTokenRefresh.Enable("{baseUrl}", "{clientId}");

For {baseUrl}, enter the address of the token server that ITokenService connects to. If you registered AddToken() without arguments, it is https://core-api.hiveaxyl.com. You can call Enable() only once. Calling it before initializing the SDK or calling it twice throws InvalidOperationException.

Warning

While the session is alive, the Hive Axyl SDK takes full charge of automatic refresh. If the app directly calls IssueTokenAsync() with the refresh_token grant type while a session exists, the refresh token in the session becomes invalid, so do not call it. The only time the app calls it directly is at restoration, when there is no session yet, as in step 2.2.

3.2. Save refreshed tokens

Tokens issued by automatic refresh are applied only to the session, not to secure storage. The refresh token changes to a new value at each refresh and the previous value becomes invalid, so if you do not replace the saved values, automatic login fails on the next launch.

The OnSessionRefreshed event is raised with the latest SessionSnapshot each time new tokens are registered in the session. Subscribe to this event and replace the saved values using the same keys as in 1. Save credentials.

using Hive.Axyl.Core;
using Hive.Axyl.Storage;

// In environments without secure storage (such as the Editor), there are no saved tokens either, so do not subscribe.
if (!HiveCore.TryResolve<ISecureStorage>(out var storage))
{
    return;
}
ISessionManager session = HiveCore.Resolve<ISessionManager>();

session.OnSessionRefreshed += async snapshot =>
{
    await storage.SaveAsync(new SecureStorageSaveRequest {
        Key   = "hive.axyl.auth.access_token",
        Value = snapshot.AccessToken,
    });
    await storage.SaveAsync(new SecureStorageSaveRequest {
        Key   = "hive.axyl.auth.refresh_token",
        Value = snapshot.RefreshToken,
    });
};

3.3. Handle refresh failures

If the Hive Axyl authentication server determines that the refresh token is invalid, automatic refresh fails, the session ends, and the OnSessionExpired event is raised. Subscribe to this event, delete the saved access token and refresh token, and direct the user to the login screen. Do not delete the guest account's guestToken and deviceKey; leave them as they are. This event is also raised when the app clears the session itself with ClearSession(), as in logout.

For refresh failures where the validity of the refresh token could not be confirmed, such as network errors, the session is kept. However, if such failures occur three times in a row, the session ends without the OnSessionExpired event, and ISessionManager.IsLoggedIn becomes false. In this case, the saved credentials are still valid, so do not delete them. Register the session again in the same way as in 2. Restore the session at app launch. For handling criteria by call result, see Automatic token refresh failures.