Authentication Basics#
This article covers the basics of how to register user accounts as well as the available authentication methods for logging in a user account to an Xsolla Backend cluster.
Account Registration#
Registering a new account in Xsolla Backend is very simple, requiring only the creation of a new account record. Due to the design of the platform setting a password during the registration process is completely optional. This guarantees flexibility in how you choose to implement authentication with your game.
A user account requires very little data, keeping the personally identifiable information to a minimum. The configurable properties of a user account are as follows:
Property |
Description |
Required |
|---|---|---|
|
The unique name of the user. |
|
|
The unique e-mail address of the user. |
|
|
The user’s real first name. |
|
|
The user’s real last name. |
|
|
The user’s real telephone number. |
|
For security reasons all the information above (except name) is removed when requesting or searching for account
data unless the user requesting that data is yourself or a system admin.
You can learn more about how these features are used by reading the Account Services documentation.
To implement user registration simply call the RegisterUser or RegisterUserAndPassword function on the
CoreSDK object instance from the SDK as shown below:
1using namespace xbe:::sdk;
2
3auto newUser = std::make_shared<models::User>();
4// Required
5newUser->SetName(_XPLATSTR("jsmith"));
6newUser->SetEmail(_XPLATSTR("john.smith@gmail.com"));
7
8// Optional
9newUser->SetFirstName(_XPLATSTR("John"));
10newUser->SetLastName(_XPLATSTR("Smith"));
11newUser->SetPhone(_XPLATSTR("+1 213-555-1234"));
12
13CoreSDK->RegisterUser(newUser).then([](pplx::task<std::shared_ptr<models::User>> task)
14{
15 try
16 {
17 task.get();
18 }
19 catch (const xbe::sdk::Exception& e)
20 {
21 // Handle error here
22 }
23});
1try
2{
3 User newUser = new()
4 {
5 // Required
6 Name = "john.smith",
7 Email = "john.smith@gmail.com",
8
9 // Optional
10 FirstName = "John",
11 LastName = "Smith",
12 Phone = "+1 213-555-1234",
13 };
14
15 await CoreSDK.RegisterUser(newUser);
16}
17catch (Exception error)
18{
19 // Handle error here
20}
1try
2{
3 const newUser: User = new User();
4 // Required
5 newUser.name = "john.smith";
6 newUser.email = "john.smith@gmail.com";
7
8 // Optional
9 newUser.firstName = "John";
10 newUser.lastName = "Smith";
11 newUser.phone = "+1 213-555-1234";
12
13 await CoreSDK.registerUser(newUser);
14}
15catch (error: any)
16{
17 // Handle error here
18}
1try
2{
3 XBECoreSDK SDK = XBECoreSDK.GetInstance();
4 User newUser = new()
5 {
6 // Required
7 Name = "john.smith",
8 Email = "john.smith@gmail.com",
9
10 // Optional
11 FirstName = "John",
12 LastName = "Smith",
13 Phone = "+1 213-555-1234",
14 };
15
16 await SDK.Instance.RegisterUser(newUser);
17}
18catch (Exception error)
19{
20 Debug.LogError($"Failed device login. Error={error.Message}");
21}
1using namespace xbe::sdk;
2
3FOnlineSubsystemXBE* OSS = (FOnlineSubsystemXBE*)(IOnlineSubsystem::Get(XBE_SUBSYSTEM));
4check(OnlineSub != nullptr);
5
6auto newUser = std::make_shared<models::User>();
7// Required
8newUser->SetName(_XPLATSTR("jsmith"));
9newUser->SetEmail(_XPLATSTR("john.smith@gmail.com"));
10
11// Optional
12newUser->SetFirstName(_XPLATSTR("John"));
13newUser->SetLastName(_XPLATSTR("Smith"));
14newUser->SetPhone(_XPLATSTR("+1 213-555-1234"));
15
16OnlineSub->CoreSDK->RegisterUser(newUser).then([]
17 pplx::task<std::shared_ptr<models::User>> task)
18{
19 try
20 {
21 task.get();
22 }
23 catch (const xbe::sdk::Exception& e)
24 {
25 // Handle error here
26 }
27});
The following example shows how to register a new account and immediately create a password for the newly created user:
1using namespace xbe::sdk;
2
3auto newUser = std::make_shared<models::User>();
4// Required
5newUser->SetName(_XPLATSTR("jsmith"));
6newUser->SetEmail(_XPLATSTR("john.smith@gmail.com"));
7
8// Optional
9newUser->SetFirstName(_XPLATSTR("John"));
10newUser->SetLastName(_XPLATSTR("Smith"));
11newUser->SetPhone(_XPLATSTR("+1 213-555-1234"));
12
13CoreSDK->RegisterUserAndPassword(newUser, _XPLATSTR("MyP@ssw0rdIsSecur3!")).then([](
14 pplx::task<std::shared_ptr<models::User>> task)
15{
16 try
17 {
18 task.get();
19 }
20 catch (const xbe::sdk::Exception& e)
21 {
22 // Handle error here
23 }
24});
1try
2{
3 User newUser = new();
4 // Required
5 newUser.Name = "john.smith";
6 newUser.Email = "john.smith@gmail.com";
7
8 // Optional
9 newUser.FirstName = "John";
10 newUser.LastName = "Smith";
11 newUser.Phone = "+1 213-555-1234";
12
13 await CoreSDK.RegisterUserAndPassword(newUser, "MyP@ssw0rdIsSecur3!");
14}
15catch (Exception error)
16{
17 // Handle error here
18}
1try
2{
3 const newUser: User = new User();
4 // Required
5 newUser.name = "john.smith";
6 newUser.email = "john.smith@gmail.com";
7
8 // Optional
9 newUser.firstName = "John";
10 newUser.lastName = "Smith";
11 newUser.phone = "+1 213-555-1234";
12
13 await CoreSDK.registerUserAndPassword(newUser, "MyP@ssw0rdIsSecur3!");
14}
15catch (error: any)
16{
17 // Handle error here
18}
1try
2{
3 XBECoreSDK SDK = XBECoreSDK.GetInstance();
4 User newUser = new();
5 // Required
6 newUser.Name = "john.smith";
7 newUser.Email = "john.smith@gmail.com";
8
9 // Optional
10 newUser.FirstName = "John";
11 newUser.LastName = "Smith";
12 newUser.Phone = "+1 213-555-1234";
13
14 await SDK.Instance.RegisterUserAndPassword(newUser, "MyP@ssw0rdIsSecur3!");
15}
16catch (Exception error)
17{
18 Debug.LogError("Failed device login. Error=" + error.Message);
19}
1using namespace xbe::sdk;
2
3FOnlineSubsystemXBE* OSS = (FOnlineSubsystemXBE*)(IOnlineSubsystem::Get(XBE_SUBSYSTEM));
4check(OnlineSub != nullptr);
5
6auto newUser = std::make_shared<models::User>();
7// Required
8newUser->SetName(_XPLATSTR("jsmith"));
9newUser->SetEmail(_XPLATSTR("john.smith@gmail.com"));
10
11// Optional
12newUser->SetFirstName(_XPLATSTR("John"));
13newUser->SetLastName(_XPLATSTR("Smith"));
14newUser->SetPhone(_XPLATSTR("+1 213-555-1234"));
15
16OnlineSub->CoreSDK->RegisterUserAndPassword(newUser, _XPLATSTR("MyP@ssw0rdIsSecur3!")).then([](
17 pplx::task<std::shared_ptr<models::User>> task)
18{
19 try
20 {
21 task.get();
22 }
23 catch (const xbe::sdk::Exception& e)
24 {
25 // Handle error here
26 }
27});
Authentication#
Xsolla Backend supports five different methods of user authentication:
API key
Password
Token
Device
Third-party (e.g. OAuth2, Facebook, Google, Twitter)
In addition to the above, multi-factor authentication (TOTP) is also supported.
API Key & Password#
Basic authentication is used to perform a standard login using a valid user identifier and password or API key.
Any valid user identifier can be used for the login name including the name, email, and phone
properties of the registered User account data.
In the below example we will assume the use of the email property as the identifier for the account created
in the previous section:
1using namespace xbe::sdk;
2
3CoreSDK->Login(_XPLATSTR("john.smith@gmail.com"), _XPLATSTR("MyP@ssw0rdIsSecur3!"))
4 .then([=](pplx::task<void> task)
5{
6 try
7 {
8 task.get();
9
10 if (CoreSDK->GetLoggedInUser() != nullptr)
11 {
12 // Success
13 }
14 else
15 {
16 // Fail
17 }
18 }
19 catch (const xbe::sdk::Exception& e)
20 {
21 // Handle error here
22 }
23});
1try
2{
3 await CoreSDK.Login("john.smith@gmail.com", "MyP@ssw0rdIsSecur3!");
4 if (CoreSDK.LoggedInUser != null)
5 {
6 // Success
7 }
8 else
9 {
10 // Fail
11 }
12}
13catch (Exception error)
14{
15 // Handle error here
16}
1try
2{
3 await CoreSDK.loginPassword("john.smith@gmail.com", "MyP@ssw0rdIsSecur3!");
4 if (CoreSDK.loggedInUser)
5 {
6 // Success
7 }
8 else
9 {
10 // Fail
11 }
12}
13catch (error: any)
14{
15 // Handle error here
16}
1try
2{
3 XBECoreSDK SDK = XBECoreSDK.GetInstance();
4 await SDK.Instance.Login("john.smith@gmail.com", "MyP@ssw0rdIsSecur3!");
5 if (CoreSDK.LoggedInUser != null)
6 {
7 // Success
8 }
9 else
10 {
11 // Fail
12 }
13}
14catch (Exception error)
15{
16 Debug.LogError($"Failed device login. Error={error.Message}");
17}
1using namespace xbe::sdk;
2
3FOnlineSubsystemXBE* OSS = (FOnlineSubsystemXBE*)(IOnlineSubsystem::Get(XBE_SUBSYSTEM));
4check(OnlineSub != nullptr);
5
6OnlineSub->CoreSDK->Login(_XPLATSTR("john.smith@gmail.com"), _XPLATSTR("MyP@ssw0rdIsSecur3!"))
7 .then([](pplx::task<void> task)
8{
9 try
10 {
11 task.get();
12
13 if (OnlineSub->CoreSDK->GetLoggedInUser() != nullptr)
14 {
15 // Success
16 }
17 else
18 {
19 // Fail
20 }
21 }
22 catch (const xbe::sdk::Exception& e)
23 {
24 // Handle error here
25 }
26});
Attention
Never store a user’s login credentials to local disk or memory. If retaining the authenticated session
between application runtimes is desired it is recommended to use the Device or Token login methods
as described below.
Token#
It is also possible to login using an existing authentication token. The token may be obtained from a previous authenticated session or provided to the application as a command line argument:
1using namespace xbe::sdk;
2
3CoreSDK->LoginToken(_XPLATSTR("<TOKEN>")).then(
4 [=](pplx::task<void> task)
5{
6 try
7 {
8 task.get();
9
10 if (CoreSDK->GetLoggedInUser() != nullptr)
11 {
12 // Success
13 }
14 else
15 {
16 // Fail
17 }
18 }
19 catch (const xbe::sdk::Exception& e)
20 {
21 // Handle error here
22 }
23});
1try
2{
3 await CoreSDK.LoginToken("<TOKEN>");
4 if (CoreSDK.LoggedInUser != null)
5 {
6 // Success
7 }
8 else
9 {
10 // Fail
11 }
12}
13catch (Exception error)
14{
15 // Handle error here
16}
1try
2{
3 await CoreSDK.loginToken("<TOKEN>");
4 if (CoreSDK.loggedInUser)
5 {
6 // Success
7 }
8 else
9 {
10 // Fail
11 }
12}
13catch (error: any)
14{
15 // Handle error here
16}
1try
2{
3 XBECoreSDK SDK = XBECoreSDK.GetInstance();
4 await SDK.Instance.LoginToken("<TOKEN>");
5 if (CoreSDK.LoggedInUser != null)
6 {
7 // Success
8 }
9 else
10 {
11 // Fail
12 }
13}
14catch (Exception error)
15{
16 Debug.LogError($"Failed device login. Error={error.Message}");
17}
1using namespace xbe::sdk;
2
3FOnlineSubsystemXBE* OSS = (FOnlineSubsystemXBE*)(IOnlineSubsystem::Get(XBE_SUBSYSTEM));
4check(OnlineSub != nullptr);
5
6OnlineSub->CoreSDK->LoginToken(_XPLATSTR("<TOKEN>"))
7 .then([](pplx::task<void> task)
8{
9 try
10 {
11 task.get();
12
13 if (OnlineSub->CoreSDK->GetLoggedInUser() != nullptr)
14 {
15 // Success
16 }
17 else
18 {
19 // Fail
20 }
21 }
22 catch (const xbe::sdk::Exception& e)
23 {
24 // Handle error here
25 }
26});
Device#
Device authentication allows a user to automatically identify themselves using a device’s unique machine identifier and deterministic secret hash. This is the recommended method for maintaining session logins between application runtimes. This method is frequently desirable to implement Frictionless Login.
Device authentication will work regardless of whether or not an existing account has been created for a given user. This works by generating a deterministic unique identifier for the device as the login name and a secret hash to serve as a special type of password. The SDK will first attempt to login using this credential. If login fails a new account is created automatically:
1CoreSDK->LoginDevice().then([](pplx::task<void> task)
2{
3 try
4 {
5 // Force the exception to be re-thrown if an error occurred.
6 task.get();
7 }
8 catch (const xbe::sdk::Exception& e)
9 {
10 // Handle error here
11 }
12});
1try
2{
3 await CoreSDK.LoginDevice();
4}
5catch (Exception error)
6{
7 // Handle error here
8}
1try
2{
3 await CoreSDK.loginDevice();
4}
5catch (error: any)
6{
7 // Handle error here
8}
1try
2{
3 XBECoreSDK SDK = XBECoreSDK.GetInstance();
4 await SDK.Instance.LoginDevice();
5}
6catch (Exception error)
7{
8 Debug.LogError($"Failed device login. Error={error.Message}");
9}
1FOnlineSubsystemXBE* OSS = (FOnlineSubsystemXBE*)(IOnlineSubsystem::Get(XBE_SUBSYSTEM));
2check(OnlineSub != nullptr);
3const IOnlineIdentityPtr IdentityInterface = OnlineSub->GetIdentityInterface();
4check(IdentityInterface.IsValid());
5
6FDelegateHandle LoginDelegateHandler;
7auto LoginDelegate = FOnLoginCompleteDelegate::CreateLambda([=](
8 int32 InLocalUserNum,
9 bool bWasSuccessful,
10 const FUniqueNetId& UserId,
11 const FString& Error)
12{
13 if (Error.Len() > 0)
14 {
15 // Handle error here
16 }
17
18 IdentityInterface->ClearOnLoginCompleteDelegate_Handle(InLocalUserNum, LoginDelegateHandler);
19});
20
21LoginDelegateHandler = IdentityInterface->AddOnLoginCompleteDelegate_Handle(0, LoginDelegate);
22IdentityInterface->AutoLogin(0);
Third-party#
Xsolla Backend supports multiple third-party authentication methods for single-sign-on including OAuth2 compatibility.
The following third-party providers are supported out of the box:
Facebook
Google
Twitter