The EOS (Epic Online Services) SDK authentication examples require a login confirmation on each startup, at least for account portal login on desktop systems. Implementing this approach in a game is absolutely not user friendly, because the player would have to re-login each time the game is started. Instead, it is much better to reuse the initial authentication. EOS offers different methods to do that.

Scope of this post

This post presents two methods to reuse EOS authentication:
(1) Persistent authentication and
(2) using a refresh token.
These methods do not depend on the game being started from the Epic Games Store.

Persistent authentication

The easiest way to reuse EOS authentication is to try “persistent authentication” and if it fails, fall back to account portal login.

Persistent auth is a special login mode which can be used by specifying the login credential type EOS_LCT_PersistentAuth (which is LoginCredentialType.PersistentAuth in C#). It is managed by the EOS SDK. As there is currently no API call available to find out whether a persistent auth is available, simply use trial and error. In general, persistent auth should be available after the initial account portal login.

EOS persistent auth process

Trying persistent auth and falling back to account portal login is very simple. See the following example code (C#), assuming OnLogin is your standard login handler:

public void LoginUsingPersistentAuth()
{
	var loginOptions = new LoginOptions()
	{
		Credentials = new Credentials()
		{
			Type = LoginCredentialType.PersistentAuth
		},
		ScopeFlags = AuthScopeFlags.BasicProfile | AuthScopeFlags.FriendsList | AuthScopeFlags.Presence
	};

	User.PlatformApplication.PlatformInterface.GetAuthInterface().Login(loginOptions, null, OnLoginUsingPersistentAuth);
}

private void OnLoginUsingPersistentAuth(LoginCallbackInfo loginCallbackInfo)
{
	if (loginCallbackInfo.ResultCode != Result.Success && Common.IsOperationComplete(loginCallbackInfo.ResultCode))
	{
		// Persistent auth failed. Try account portal login and delete persistent auth settings to avoid problems.
		var deletePersistentAuthOptions = new DeletePersistentAuthOptions();
		User.PlatformApplication.PlatformInterface.GetAuthInterface().DeletePersistentAuth(deletePersistentAuthOptions, null, OnDeletePersistentAuth);

		var loginOptions = new LoginOptions()
		{
			Credentials = new Credentials()
			{
				Type = LoginCredentialType.AccountPortal
			},
			ScopeFlags = AuthScopeFlags.BasicProfile | AuthScopeFlags.FriendsList | AuthScopeFlags.Presence
		};

		User.PlatformApplication.PlatformInterface.GetAuthInterface().Login(loginOptions, null, OnLogin);
	}
	else
	{
		// Persistent auth succeeded. We are logged in.
		OnLogin(loginCallbackInfo);
	}
}

Using a refresh token

While I would recommend to use persistent auth in order to reuse EOS authentication, there are some use cases in which this approach cannot be used. For example, you may need to store the login state separately in a game backend. Or you may be running the EOS login in a launcher and need to reuse the authentication in a platform-independent way.

Especially for the later use case, EOS provides a “refresh token” as part of the auth token. The refresh token can be used to re-login, and it can be temporarily stored so that it is available after application restart. It is available after successful login and can be used for a limited time (currently less than a day). However, it is refreshed on every login with a new time limit.

// Retrieve a copy of the refresh token using EOS C# API.
// You need the EOS local user id for this call.
// It is supplied for example in the EOS OnLogin Callback, callbackInfo.LocalUserId
CopyUserAuthTokenOptions tokenOptions = new CopyUserAuthTokenOptions();
User.PlatformApplication.PlatformInterface.GetAuthInterface().CopyUserAuthToken(
	tokenOptions, localUserId, out Token token);
// token.RefreshToken contains the RefreshToken, and token.RefreshExpiresAt its expiry.

After copying the refresh token, it can be used to login non-interactively with credential type EOS_LCT_RefreshToken (which is LoginCredentialType.RefreshToken in C#). Note, however, that this token is single use only, and it is no longer valid after logging out.

public void LoginUsingRefreshToken(string refreshToken)
{
	var loginOptions = new LoginOptions()
	{
		Credentials = new Credentials()
		{
			Type = LoginCredentialType.RefreshToken,
			Token = refreshToken // The token which was copied after successfull login.
		},
		ScopeFlags = AuthScopeFlags.BasicProfile | AuthScopeFlags.FriendsList | AuthScopeFlags.Presence
	};

	User.PlatformApplication.PlatformInterface.GetAuthInterface().Login(loginOptions, null, OnLoginUsingRefreshToken);
}

private void OnLoginUsingRefreshToken(LoginCallbackInfo loginCallbackInfo)
{
	if (loginCallbackInfo.ResultCode != Result.Success && Common.IsOperationComplete(loginCallbackInfo.ResultCode))
	{
		// Login using Refresh Token failed.
		// Implement fallback or forward error.
	}
	else
	{
		// Refresh token auth succeeded. We are logged in.
		OnLogin(loginCallbackInfo);
	}
}

A note on security

The refresh token enables a full login on behalf of the user and therefore needs to be handled with care. Access to this token should be limited to the corresponding user. I would recommend to use a secure storage like the Windows Credential Store if you need to store the refresh token. See e.g. CredentialManager.

Epic and Epic Games are trademarks or registered trademarks of Epic Games, Inc. in the United States of America and elsewhere.