Signing local users in and out
The identity system provides an API to sign players in and out of Epic Online Services, similar to the IOnlineIdentity interface, but independent of the online subsystem APIs. Internally the plugin uses the identity system to implement the IOnlineIdentity
interface, but you can also use it directly if you prefer the API structure.
The C++ APIs described in this section are only available in the Marketplace Edition, as the Free Edition does not ship with any C++ headers.
Updating your game module dependencies
Before you can access the identity system, you need to update your game module's .Build.cs
file to depend on the RedpointEOSIdentity
module, like so:
PrivateDependencyModuleNames.AddRange(new string[]
{
"RedpointEOSIdentity",
});
Obtaining the identity system
To obtain a reference to the identity system, call GetSystem<IIdentitySystem>
on an FPlatformHandle
you previously obtained:
#include "RedpointEOSIdentity/IdentitySystem.h"
// Place at the top of function bodies that use the identity system.
using namespace ::Redpoint::EOS::Identity;
FPlatformHandle PlatformHandle; // e.g. obtained from the online subsystem.
auto Identity = PlatformHandle->GetSystem<IIdentitySystem>();
The FIdentityUser type
When users are signed into Epic Online Services, the identity system APIs will return shared references to FIdentityUser
instances, which provide the following information:
GetUserSlot
: The local "slot" that this user is signed into, commonly also known as the "controller index". The "user slot" is only used for games which support multiple local players.GetUserId
: The ID of the user that thisFIdentityUser
instance represents. TheFIdentityUserId
type is an alias ofUE::Online::FAccountId
, so you can use the documented user ID functions to convert the user ID returned from this function to and from various types (including serializing and deserializing to string values).GetRefreshCallback
: The delegate which will refresh authentication with the EOS backend when the current login token expires. The identity system internally uses this to keep local players signed in, and you should not need to call it yourself.GetExternalCredentials
: If this user was authenticated using a local platform such as Steam, theIOnlineExternalCredentials
instance returned by this function contains metadata about that external authentication, including the underlying token and attributes used to authenticate.GetCrossPlatformAccountId
: If this user is signed into a cross-platform account such as an Epic Games account, this is the cross-platform account ID. When using Epic Games as the cross-platform account provider, this will be the ID of the Epic Games account.GetProcessGlobalUserHandle
: The "process-wide" unique handle for this signed in user, as aFPlatformUserId
value. This is used by theIVoiceChatUser::Login
API to disambiguate signed in users across multiple play-in-editor windows.GetAuthenticationAttributeKeys
: The authentication attributes for this locally signed in user. These are the same attributes available onFUserOnlineAccount
.TryGetAuthenticationAttributeValue
: Attempt to retrieve the value of the specified authentication attribute. You must use this call if you want to access the value ofcrossPlatform.canLink
,idToken
orepic.idToken
attributes, as they are not returned byGetStaticAuthenticationAttributes
.GetStaticAuthenticationAttributes
: Returns a map of authentication attributes that are not dynamic (seeTryGetAuthenticationAttributeValue
above for a list of attribute values not returned in the resulting map).GetIdToken
: Returns the EOS Connect ID Token. This returns the same value as callingTryGetAuthenticationAttributeValue
for theidToken
authentication attribute.GetUserInfo
: Returns theFUserInfo
fetched through the user cache system for this locally signed in user.
Signing a local user in
To sign a local player into Epic Online Services, use IIdentitySystem::Login
like so:
Identity->Login(
FLoginRequest(0 /* user slot / controller index */)
IIdentitySystem::FOnLoginComplete::CreateSPLambda(this, [this](FError ErrorCode, FIdentityUserPtr NewUser) {
if (*ErrorCode.bWasSuccessful)
{
// NewUser is valid.
}
}));
If you've written a custom authentication graph, and you need to pass in Type
, Id
or Token
for FAuthenticationGraphState::ProvidedCredentials
, use the variant of the FLoginRequest
contructor that passes these values:
Identity->Login(
FLoginRequest(0, TEXT("Type"), TEXT("Id"), TEXT("Token"))
IIdentitySystem::FOnLoginComplete::CreateSPLambda(this, [this](FError ErrorCode, FIdentityUserPtr NewUser) {
if (*ErrorCode.bWasSuccessful)
{
// NewUser is valid.
}
}));
Signing a local user out
To sign a local player out of Epic Online Services, use IIdentitySystem::Logout
like so:
Identity->Logout(
FLogoutRequest(0 /* user slot / controller index */)
IIdentitySystem::FOnLogoutComplete::CreateSPLambda(this, [this](FError ErrorCode) {
if (*ErrorCode.bWasSuccessful)
{
// Local user was signed out.
}
}));
Getting notified when local users sign in and out
If you need to be notified when players are signed in and out of user slots, you can use the IIdentitySystem::OnUserSlotChanged
event like so:
// To start receiving event notifications:
FDelegateHandle Handle = Identity->OnUserSlotChanged().AddSPLambda(this, [this](
FIdentityUserSlot UserSlot,
EIdentityUserSlotState OldUserSlotState,
FIdentityUserId OldUserId,
EIdentityUserSlotState NewUserSlotState,
FIdentityUserId NewUserId,
EIdentityUserSlotChangeReason ChangeReason) {
// UserSlot - The user slot / controller index that changed state.
// OldUserSlotState - The previous state, either NotSignedIn or SignedIn.
// OldUserId - If the previous state was SignedIn, the user ID that was previously signed into this user slot.
// NewUserSlotState - The new state, either NotSignedIn or SignedIn.
// NewUserId - If the new state was SignedIn, the user ID that is now signed into this user slot.
// ChangeReason - The reason why this user slot is changing state:
// - ExplicitLogin: `IIdentitySystem::Login` was called when initially signed out and completed successfully.
// - ExplicitLogout: `IIdentitySystem::Logout` was called when initially signed in and completed successfully.
// - ExplicitLink: `IIdentitySystem::Login` was called while signed in and with a local user
// account that could link to a cross-platform account. The user successfully linked their
// local platform account to a cross-platform (Epic Games) account. When the change reason is
// ExplicitLink, the old and new slot state will both be SignedIn and the old and new user ID
// will be identical.
});
// Later, when you no longer need to receive event notifications:
Identity->OnUserSlotChanged().Remove(Handle);
Getting the locally signed in user by user slot
To get the currently signed in user for a user slot (controller index), use IIdentitySystem::GetUser(FIdentityUserSlot)
:
FIdentityUserPtr LocalUser = Identity->GetUser(0 /* user slot / controller index */);
// @note: LocalUser may be nullptr if there is no user signed into that user slot / controller index.
Getting the locally signed in user by user ID
To get a currently signed in user by their user ID, use IIdentitySystem::GetUser(FIdentityUserId)
:
FIdentityUserPtr LocalUser = Identity->GetUser(/* ... */);
// @note: LocalUser may be nullptr if the specified user ID is not currently signed in.
Getting all locally signed in users
To get all users that are currently signed in, use IIdentitySystem::GetUsers
:
TArray<FIdentityUserRef> LocalUsers = Identity->GetUsers();
Hooking into the identity system
The identity system provides hooks that you can use to intercept and alter the way sign in and sign out works in your game. These hooks are used internally by the plugin so notify all the relevant components when the login state changes, but you can write your own custom hooks to influence the login process.
To write an identity system hook, you need to declare a class that inherits from IIdentityHook
. All of the functions on this interface are optional to implement - any you omit will have no effect. The available hook functions are:
OnPreLogin
: AfterIIdentitySystem::Login
is called, but before authentication starts. If you return an error in theOnComplete
callback, theIIdentitySystem::Login
call fails with that error. You can use this to prevent login from starting based on the current game state.OnPostLoginBeforeEvents
: After the authentication process completes (not necessarily successfully) as part ofIIdentitySystem::Login
, but before theIIdentitySystem::OnUserSlotChanged
event is fired. This allows you to set up any internal state before code relying onIIdentitySystem::OnUserSlotChanged
event notifications runs. Internally the plugin uses this to update theFUniqueNetId
of local player states and player controllers, so that any blueprint code that runs in response to login completing will see valid player IDs on the local player controllers. If you return an error in theOnComplete
callback, theIIdentitySystem::Login
call will log the error but otherwise continue as it normally would.OnPostLoginAfterEvents
: After the authentication process completes (not necessarily successfully) as part ofIIdentitySystem::Login
, after theIIdentitySystem::OnUserSlotChanged
event is fired. This otherwise has the same semantics asOnPostLoginBeforeEvents
.OnPreLogout
: AfterIIdentitySystem::Logout
is called, but before the user is signed out. If you return an error in theOnComplete
callback, theIIdentitySystem::Logout
call fails with that error and the user remains signed in. You can use this to prevent logout from starting based on the current game state.OnPreUnexpectedLogout
: Called when the EOS SDK notifies us that the user has been unexpectedly signed out (typically due to an automatic credential refresh failing). This occurs before the user is internally signed out in the plugin, but you will not be able to call any EOS SDK functions at this point, as the user has already been signed out of Epic Online Services. Any error returned from theOnComplete
callback is ignored, as unexpected logouts can not be cancelled. You can use this callback to notify the local player that they need to sign in again or otherwise return them to the main menu.OnPostLogoutBeforeEvents
/OnPostLogoutAfterEvents
: These are the logout versions ofOnPostLoginBeforeEvents
/OnPostLoginAfterEvents
and have the same semantics except that they fire in response to theIIdentitySystem::Logout
call instead ofIIdentitySystem::Login
.OnStartSystem
: After the user is successfully signed in, or after the logout attempt fails. You can use this hook to start any background systems that need to track local users or perform periodic operations on them. If you return an error in the OnComplete callback, the identity system will log the error but otherwise continue as it normally would.OnStopSystem
: AfterIIdentitySystem::Logout
is called and pre-logout hooks have run, but before the user is actually signed out. You should use this if implementingOnStartSystem
and cease any API calls that use the local user after this hook runs. If you return an error in the OnComplete callback, the identity system will log the error but otherwise continue as it normally would.OnPostCredentialRefresh
: Called when the identity system automatically refreshes credentials for a local player in response to an upcoming credential expiry. For example, when playing on Steam, the EOS SDK requires the plugin to periodically refresh authentication with the EOS backend by providing a new Steam session ticket, and this call is invoked once that credential refresh process completes (not necessarily successfully). IfbWasSuccessful
was true, the authentication attributes of theFIdentityUser
and the token available onIOnlineExternalCredentials
may have new values.OnGetAdditionalAuthenticationAttributeKeys
: Called by the identity system to populate authentication attribute keys onFIdentityUser
. You can use this to dynamically provide authentication attributes for local users so they're visible in other systems.OnGetAdditionalAuthenticationAttributeValue
: Called by the identity system to retrieve the value for authentication attribute keys onFIdentityUser
that were dynamically added throughOnGetAdditionalAuthenticationAttributeKeys
.OnAuthenticationUserInterfaceRequired
: Called by the identity system to get theIAuthenticationGraphUserInterface
implementation, which is used by theRedpointEOSAuth
module to display UI widgets on screen or in XR/VR when the login process has an interactive step. You should not need to override this in a hook as the plugin already provides a hook that implements it.
To register and unregister your hook, you should use FIdentityHookRegistry
on the startup and shutdown of your game module:
class FMyGameModule : public FDefaultModuleImpl
{
private:
TSharedPtr<IIdentityHook> MyIdentityHook;
public:
virtual void StartupModule() override
{
using namespace ::Redpoint::EOS::Identity;
this->MyIdentityHook = MakeShared<FMyIdentityHook>();
FIdentityHookRegistry::RegisterHook(this->MyIdentityHook.ToSharedRef());
};
virtual void ShutdownModule() override
{
using namespace ::Redpoint::EOS::Identity;
if (this->MyIdentityHook.IsValid())
{
FIdentityHookRegistry::UnregisterHook(this->MyIdentityHook.ToSharedRef());
}
}
};
To find examples of existing identity hooks, search for public IIdentityHook
in the plugin source code, as the plugin internally defines several hooks necessary for wiring up various components in response to local users signing in and out.