Re-login using cached refresh tokens
Overview
The AccelByte Gaming Services (AGS) Game SDK allows game developers to implement the re-login feature so that users in a game can remain logged in using a cached refresh token. This capability is useful to authenticate a player when a third-party service is down or under maintenance. The user can be logged in using the refresh token for 24 hours.
Implementation
The AGS Game SDK logs the player in successfully first using the LoginWithOtherPlatform
function from the AGS User API. If the login succeeds, then the refresh token will be generated and cached automatically. The caching does not need an explicit call. After that point, the ReloginWithOtherPlatform
function can be used when the platform service is down or unavailable, and the re-login API will use the last generated platform refresh_token
to log in to the AGS platform.
Examples of the implementation using the Steam service can be seen below.
- Unreal
- Unreal OSS
- Unity
//Try to login using Steam first
FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();
FString SteamTicket = GetSteamTicket(); // using UnrealEngine Online Subsystem Steam
bool bLoginDone = false;
bool bLoginUsingSteamAccountSuccess = false;
ApiClient->User.LoginWithOtherPlatform(EAccelBytePlatformType::Steam, SteamTicket,
FVoidHandler::CreateLambda([&]()
{
bLoginDone = true;
bLoginUsingSteamAccountSuccess = true;
}),
FErrorHandler::CreateLambda([&](int32 Code, FString Message)
{
bLoginDone = true;
}));
WaitUntil([&]() { return bLoginDone; }, "Waiting...");
FString SteamID = GetSteamUserId(); // using Steamworks
/// EXAMPLE:
/// FString GetSteamUserId()
/// {
/// SteamID SteamID = SteamUser()->GetSteamID();
/// uint64 SteamIdLong = SteamID.ConvertToUint64();
/// return FString::Printf(TEXT("%llu"), SteamIdLong);
/// }
if (bLoginUsingSteamAccountSuccess)
{
return;
}
// When login using a Steam account failed due to any reason (i.e., Steam API is down)
// Use this example to re-login using cached refresh token
bool bReloginDone = false;
bool bReloginSuccess = false;
ApiClient->User.TryRelogin(SteamID,
FVoidHandler::CreateLambda([&]()
{
bReloginDone = true;
bReloginSuccess = true;
}),
FErrorHandler::CreateLambda([&](int32 Code, FString Message)
{
bReloginDone = true;
}));
WaitUntil([&]() { return bReloginDone; }, "Waiting...");
/// EXAMPLE: including Steamworks to your project .build.cs
/// FString GetSteamUserId()
/// {
/// SteamID SteamID = SteamUser()->GetSteamID();
/// uint64 SteamIdLong = SteamID.ConvertToUint64();
/// return FString::Printf(TEXT("%llu"), SteamIdLong);
/// }
FString SteamUserID = GetSteamUserId(); //Example of SteamUserID
int32 PlayerInputIndex = GetInputIndex(); //Example of the index
FOnlineAccountCredentials LoginCreds;
LoginCreds.Type = "CachedToken";
LoginCreds.Id = SteamUserID;
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(GetWorld());
const IOnlineIdentityPtr IdentityInterface = Subsystem->GetIdentityInterface();
IdentityInterface->Login(PlayerInputIndex, LoginCreds);
For more information, refer to Set up Steam as an identity provider.
using AccelByte.Core;
using AccelByte.Models;
using UnityEngine;
using Steamworks;
public class Main: MonoBehaviour
{
public const string GameIdentity = "yourIdentity";
void Start()
{
GenerateSteamTicket(GameIdentity, OnGetSteamTicketDone);
}
private void OnGetSteamTicketDone(string steamTicket)
{
AccelByte.Api.User user = AccelByteSDK.GetClientRegistry().GetApi().GetUser();
if (string.IsNullOrEmpty(steamTicket))
{
Debug.LogError("Steam ticket is empty, re-login with previous token");
AutoReloginSteam();
return;
}
string steamToken = $"{GameIdentity}:{steamTicket}";
user.LoginWithOtherPlatform(AccelByte.Models.PlatformType.Steam, steamToken, OnLoginWithSteamDone);
}
private void OnLoginWithSteamDone(Result<TokenData, OAuthError> loginResult)
{
if (loginResult.IsError)
{
AutoReloginSteam();
}
else
{
Debug.Log("Login success");
}
}
private void AutoReloginSteam()
{
AccelByte.Api.User user = AccelByteSDK.GetClientRegistry().GetApi().GetUser();
user.ReloginWithOtherPlatform(PlatformType.Steam, reloginResult =>
{
if (reloginResult.IsError)
{
Debug.LogError(reloginResult.Error.error_description);
}
else
{
Debug.Log("Relogin success");
}
});
}
}