> For the complete documentation index, see [llms.txt](https://docs.coherence.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coherence.io/2.4/hosting/coherence-cloud/authentication-service-player-accounts.md).

# Player Accounts

**Player Accounts** can be used to authenticate players, uniquely identify them across multiple devices, and give them access to [coherence Cloud's services](/2.4/hosting/coherence-cloud/game-services.md).

## CoherenceCloud API

The [**CoherenceCloud** **API**](https://unityapi.coherence.io/docs/v2.2.0/api/Coherence.Cloud.CoherenceCloud.html) provides many ways to authenticate your players with [coherence Cloud](/2.4/hosting/coherence-cloud.md):

* [Login As Guest](#login-as-guest)
* [Login With Password](#login-with-password)
* [Login With Session Token](#login-with-session-token)
* [Login With Steam](#login-with-steam)
* [Login With Epic Games](#login-with-epic-games)
* [Login With PlayStation](#login-with-playstation)
* [Login With Xbox](#login-with-xbox)
* [Login With Nintendo](#login-with-nintendo)
* [Login With Game Center](#login-with-game-center)
* [Login With JWT](#login-with-jwt)
* [Login With One-Time Code](#login-with-one-time-code)

{% hint style="info" %}
You can also use the [CoherenceCloudLogin component](/2.4/manual/components/coherence-cloud-login.md) log in to coherence Cloud automatically.
{% endhint %}

### Login As Guest

You can use **CoherenceCloud.LoginAsGuest** to log in to coherence Cloud using a guest account that is automatically generated for you.

Guest IDs are stored locally on the device, so it is important to know that uninstalling the game will also wipe out the data for the guest account, and players will no longer be able to access it even if they install the game again.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginAsGuestExample : MonoBehaviour
{
    public PlayerAccount PlayerAccount { get; private set; }

    async void Start()
    {
        PlayerAccount = await CoherenceCloud.LoginAsGuest();
        Debug.Log($"Logged in as: {PlayerAccount}.");
    }
}
```

{% hint style="info" %}
**Guest Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With Password

You can use **CoherenceCloud.LoginWithPassword** to log in to the coherence Cloud using a username and password.

An **autoSignup** value of **true** can be passed to the method to automatically create a new coherence Cloud account with the provided username and password, if one does not exist already. The default value of **autoSignup** is **false**.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithPasswordExample : MonoBehaviour
{
    [SerializeField] string username;
    [SerializeField] string password;
    [SerializeField] bool autoSignup;

    public PlayerAccount PlayerAccount { get; private set; }

    async void Start()
    {
        PlayerAccount = await CoherenceCloud.LoginWithPassword(username, password, autoSignup);
        Debug.Log($"Logged in as: {PlayerAccount}.");
    }
}
```

{% hint style="info" %}
**User / Password Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With Session Token

You can use **CoherenceCloud.LoginWithSessionToken** to log in to coherence Cloud using a session token acquired from a previously login operation.

This can be useful to avoid users from having to re-enter their username and password every time they want to log in.

Session tokens will expire after a certain period of time after the last login operation.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithSessionTokenExample : MonoBehaviour
{
    [SerializeField] GameObject loginUi;

    async void Start()
    {
        var sessionToken = SessionToken.Deserialize(PlayerPrefs.GetString("SessionToken", ""));
        if  (sessionToken == SessionToken.None)
        {
            Debug.Log("No session token found. Showing login UI...");
            Instantiate(loginUi);
            return;
        }

        var loginOperation = await CoherenceCloud.LoginWithSessionToken(sessionToken);
        if (loginOperation.HasFailed)
        {
            Debug.LogWarning(loginOperation);
            Debug.Log("Logging in using session token failed. The session token may have expired. Showing login UI...");
            Instantiate(loginUi);
            return;
        }

        var playerAccount = loginOperation.Result;
        PlayerPrefs.SetString("SessionToken", SessionToken.Serialize(playerAccount.SessionToken));
        Debug.Log($"Logged in as: {playerAccount}.");
    }
}
```

### Login With Steam

You can use **CoherenceCloud.LoginWithSteam** to log in to the coherence Cloud using a Steam account.

To do so, you have to provide at least an authentication ticket for the Steam User that you want to log in as. You get it from the [SteamUser.GetAuthTicketForWebApi](https://partner.steamgames.com/doc/api/ISteamUser#GetAuthTicketForWebApi).

If you passed an identity string to the **SteamUser.GetAuthTicketForWebApi** method, you should also pass that same identity to the **CoherenceCloud.LoginWithSteam** method.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithSteamExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> Login(string ticket, string identity = null)
    {
        PlayerAccount playerAccount = await CoherenceCloud.LoginWithSteam(ticket, identity);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**Steam Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With Epic Games

You can use **CoherenceCloud.LoginWithEpicGames** to log in to the coherence Cloud using an Epic Games account.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithEpicGamesExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> Login(string token)
    {
        PlayerAccount playerAccount = await CoherenceCloud.LoginWithEpicGames(token);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**Epic Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With PlayStation

You can use **CoherenceCloud.LoginWithPlayStation** to log in to the coherence Cloud using a PlayStation Network account.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithPlayStationExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> Login(string token)
    {
        PlayerAccount playerAccount = await CoherenceCloud.LoginWithPlayStation(token);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**PSN Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With Xbox

You can use **CoherenceCloud.LoginWithXbox** to log in to the coherence Cloud using an Xbox account.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithXboxExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> Login(string token)
    {
        PlayerAccount playerAccount = await CoherenceCloud.LoginWithXbox(token);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**Xbox Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With Nintendo

You can use **CoherenceCloud.LoginWithNintendo** to log in to the coherence Cloud using a Nintendo Services account.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithNintendoExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> Login(string token)
    {
        PlayerAccount playerAccount = await CoherenceCloud.LoginWithNintendo(token);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**Nintendo Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With Game Center

Use **CoherenceCloud.LoginWithGameCenter** to log in to the coherence Cloud using a Game Center account.

The credentials are the output of **fetchItems(forIdentityVerificationSignature:)** on [GKLocalPlayer](https://developer.apple.com/documentation/gamekit/gklocalplayer), which your game fetches itself (coherence doesn't call GameKit). Wrap them in a **GameCenterCredentials** value and pass that to the login method. The signature is only valid for about an hour, so fetch a fresh one for each login attempt rather than caching it.

```csharp
using System.Threading.Tasks;
using Coherence.Cloud;
using UnityEngine;

class LoginWithGameCenter : MonoBehaviour
{
    // The credentials come from GameKit's fetchItems(forIdentityVerificationSignature:), which the
    // title fetches itself. Pass GKLocalPlayer.teamPlayerID (not gamePlayerID), and only call this
    // when GKPlayer.scopedIDsArePersistent() is true.
    public async Task<PlayerAccount> Login(string teamPlayerId, string bundleId, string publicKeyUrl,
        byte[] signature, byte[] salt, ulong timestamp)
    {
        var credentials = new GameCenterCredentials(teamPlayerId, bundleId, publicKeyUrl, signature, salt, timestamp);
        PlayerAccount playerAccount = await CoherenceCloud.LoginWithGameCenter(credentials);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**Game Center Auth Enabled** must be ticked, and the application's bundle identifier added to the allowed bundle identifiers, in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md).
{% endhint %}

{% hint style="warning" %}
Pass **GKLocalPlayer.teamPlayerID**, not **gamePlayerID**.
{% endhint %}

{% hint style="danger" %}
Only log in when **scopedIDsArePersistent()** on [GKPlayer](https://developer.apple.com/documentation/gamekit/gkplayer) returns **true**. When it returns false (for guest players, and for some identity-less states) GameKit hands out identifiers that change every session, so every login creates a new Player Account that the player can never return to.
{% endhint %}

### Login With JWT

You can use **CoherenceCloud.LoginWithJwt** to log in to the coherence Cloud using a custom JSON Web Token.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LoginWithJwtExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> Login(string token)
    {
        var playerAccount = await CoherenceCloud.LoginWithJwt(token);
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**JWT Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

### Login With One-Time Code

You can use **CoherenceCloud.LoginWithOneTimeCode** to log in to the coherence Cloud using a temporary code acquired from another device using **PlayerAccount.GetOneTimeCode**.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class AcquireOneTimeCodeExample : MonoBehaviour
{
    async void Start()
    {
        PlayerAccount playerAccount = await CoherenceCloud.LoginAsGuest();
        string oneTimeCode = await playerAccount.GetOneTimeCode();
        Debug.Log($"Login with this code on your other device: {oneTimeCode}.");
    }
}

public class LoginWithOneTimeCodeExample : MonoBehaviour
{
    public async Awaitable<PlayerAccount> LoginWithOneTimeCode(string oneTimeCode)
    {
        var loginOperation = await CoherenceCloud.LoginWithOneTimeCode(oneTimeCode);
        if (loginOperation.HasFailed)
        {
            Debug.LogWarning($"Logging in failed. The code may have already expired.\n{loginOperation}.");
            return null;
        }

        var playerAccount = loginOperation.Result;
        Debug.Log($"Logged in as: {playerAccount}.");
        return playerAccount;
    }
}
```

{% hint style="info" %}
**One-Time Code Auth Enabled** must be ticked in Project Settings on your [Online Dashboard](/2.4/hosting/coherence-cloud/online-dashboard.md) for this authentication method to be usable.
{% endhint %}

## Linking

If you want to add multiple authentication methods to the same Player Account, you can do so by first logging in using any of of the authentication methods, and then linking the rest of the authentication methods using the Link methods on the PlayerAccount class.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class LinkGuestExample : MonoBehaviour
{
    async void Start()
    {
        PlayerAccount mainPlayerAccount = await PlayerAccount.GetMainAsync();

        // Acquire Guest Id from guest account associated with this machine.
        PlayerAccount guestPlayerAccount = await CoherenceCloud.LoginAsGuest();
        GuestId guestId = guestPlayerAccount.GuestId.Value;
        guestPlayerAccount.Logout();

        // Link the guest id to the main account:
        await mainPlayerAccount.LinkGuest(guestId, force: true);
    }
}
```

The PlayerAccount class provides the following methods for linking authentication methods into an existing Player Account:

* **LinkGuest**
* **LinkSteam**
* **LinkEpicGames**
* **LinkPlayStation**
* **LinkXbox**
* **LinkNintendo**
* **LinkGameCenter**
* **LinkJwt**

## Unlinking

Each of the **Link** methods listed above also have a corresponding **Unlink** method in the PlayerAccount class that can be used to remove an authentication method from the Player Account.

If an authentication method is already linked with one Player Account, and you try to link it with another one, the operation will fail by default. If however you pass a **force** value of **true** to a Link method, then the authentication method will automatically be unlinked from any existing Player Accounts it's associated with.

{% hint style="warning" %}
**GetInfo does not reflect a Link or Unlink immediately.** Requests to the same endpoint are throttled per method, with an interval of about a second. A **GET** made inside that window is answered with the **previous response**, reported as a success rather than as an error, so calling [PlayerAccount.GetInfo](https://unityapi.coherence.io/docs/v2.2.0/api/Coherence.Cloud.PlayerAccount.GetInfo.html) right after a Link or Unlink can return the identity list from before the change.

Do not treat an immediate read as confirmation that a Link or Unlink took effect: the operation's own result already tells you whether it succeeded. If your game needs to display the identity list right after changing it, re-read it after a short delay, or retry until it reflects the change.
{% endhint %}

{% hint style="danger" %}
**Warning**: If an authentication method is unlinked from a Player Account, and the Player Account has no other authentication methods set up, then access to that Player Account will be lost.
{% endhint %}

## Account Information

### Username and Password

You can change the username and (optionally) password of a Player Account using **PlayerAccount.SetUsername**.

If no password is provided, then the option to [login with password](#login-with-password) will not be available. This might still be useful if the username is used for game purposes only and not as an authentication method.

You can remove the username and password from a Player Account using **PlayerAccount.RemoveUsername**.

If the Player Account has no other authentication methods set up besides the username and password, then **RemoveUsername** will fail by default. If however you pass a **force** value of **true** to the method, then the username and password will be removed regardless.

{% hint style="danger" %}
**Warning**: Access to a Player Account will be lost if the last authentication method is removed from it.
{% endhint %}

### Display Name and Image

You can change the display name and image of a Player Account using **PlayerAccount.SetDisplayInformation**.

You can remove the display name and image from a Player Account using **PlayerAccount.RemoveDisplayInformation**.

### Email

You can assign an email address to a Player Account using **PlayerAccount.SetEmail**.

You can remove an email address from a Player Account using **PlayerAccount.RemoveEmail**.

## Player Account Id

A globally unique identifier gets generated for every player account that is created. This id can be accessed via [PlayerAccount.Id](https://unityapi.coherence.io/docs/v2.2.0/api/Coherence.Cloud.PlayerAccount.Id.html#Coherence_Cloud_PlayerAccount_Id).

The id can be useful for storing player-specific data in [Cloud Storage](/2.4/hosting/coherence-cloud/game-services/cloud-storage.md).

```csharp
public class PlayerAccountIdExample : MonoBehaviour
{
    private class PlayerData
    {
        public string Name;
        public int Level;
        public override string ToString() => $"Player: {Name} (lv {Level})";
    }

    private async void Start()
    {
        var cloudService = CloudService.ForClient();
        PlayerAccount playerAccount = await PlayerAccount.GetMainAsync();

        // Create an identifier for a storage object
        // that can hold player-specific data
        // based on the player's account's identifier:
        var storageObjectId = new StorageObjectId("PlayerData", playerAccount.Id.ToString());

        var loadOperation = await cloudService.CloudStorage.LoadObjectAsync<PlayerData>(storageObjectId);
        if (loadOperation.IsCompletedSuccessfully)
        {
            Debug.Log("Loaded player data: " + loadOperation.Result);
        }
    }
}
```
