Service and access token support
In modules, the IExecutionContext
interface provides an AccessToken
and a ServiceToken
.
Token type | Origin | Data access | Usage |
---|---|---|---|
accessToken | Generated by the Authentication service. | Only the authenticated player. | The AccessToken is the JWT you use to authenticate a Cloud Code call. You can pass the token on to other UGS services to access data for the authenticated player. |
serviceToken | Generated by Cloud Code. | Cross-player data access. | The ServiceToken is a the token you use to call out to other UGS services and interact with cross-player data. |
You can authenticate as a player or as Cloud Code with these tokens when you call other UGS services.
Refer to Authentication page for more information.
Overview
Evaluate whether you want to authenticate as a player or as a trusted client.
The module IExecutionContext
interface provides you with a AccessToken
and a ServiceToken
.
If the purpose of the module is to only access the data of the authenticated player, you should use the AccessToken
to authenticate as the player calling the module endpoint. This ensures that the player can only access and interact with their own data.
If the purpose of the module is to access cross-player data, you should use the ServiceToken
to authenticate as Cloud Code. This will ensure that the module can access and interact with cross-player data.
However, this creates an opening for malicious players to call the module endpoint and access cross-player data where not intended. To prevent this, you should ensure that the module is protected with Access Control rules.
To learn more about how you can interact with cross-player data, refer to the Cross-player data documentation.
Access token support
An access token is a JWT that the Authentication service(https://docs.unity.com/ugs/manual/authentication/manual/use-anon-sign-in) generates. You can use the access token to authenticate players.
When an authenticated player calls a Cloud Code module, they pass their access token to the module as the AccessToken
property of the IExecutionContext
interface.
You can use access tokens with the Cloud Code C# Game SDKs. To use access tokens with other UGS APIs, you need to pass the token as a bearer token in the Authentication header.
Supported services
To check which services support access tokens, refer to the table below:
Provider | Supported services |
---|---|
Cloud Code C# Client SDKs | All Cloud Code C# Client SDKs support the same access tokens as their corresponding service APIs. |
UGS Client APIs | All UGS services that support the Authentication service. |
Cloud Code C# Admin SDKs | Not supported. Use Service Account authentication instead. |
UGS Admin APIs | Not supported. Use Service Account authentication instead. |
Note: Most UGS services are onboarded with the Authentication service and support access tokens.
Use tokens with Cloud Code C# Client SDKs
To use the AccessToken
with the Cloud Code C# Client SDKs, you need to pass the token from the IExecutionContext
interface.
The example below increments the currency balance for the player that calls the module:
C#
[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId)
{
...
try
{
// Increment the balance of the currency for the player calling the module
var res = await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.AccessToken,
ctx.ProjectId, ctx.PlayerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));
_logger.LogInformation("Incremented currency {currencyId} balance by {amount}", currencyId, 10);
return res;
}
catch (ApiException e)
{
_logger.LogError("Failed to increment {currencyId} balance for the player. Error: {error}", currencyId, e.Message);
throw new Exception($"Failed to increment {currencyId} balance for playerId {ctx.PlayerId}. Error: {e.Message}");
}
}
Use with UGS Client APIs
To use the AccessToken
with the UGS Client APIs, pass the token as a bearer token in the Authentication header.
Note: If the service you want to call provides a Cloud Code C# SDK, you can use the SDK instead of calling the service API directly. For a list of available SDKs, refer to Available libraries page.
C#
public class Relationships
{
private readonly RestClient _httpClient;
public Relationships()
{
_httpClient = new RestClient("https://social.services.api.unity.com/v1/relationships");
}
public async Task<List<RelationshipsApiResponse?>> GetRelationships(IExecutionContext context)
{
var request = new RestRequest()
{
// Pass the access token as a bearer token in the header
Authenticator = new JwtAuthenticator(context.AccessToken)
};
....
}
}
Service token support
A service token is a JWT that Cloud Code generates. You can use service tokens to authenticate services as Cloud Code. This is a service account token that's gone through the Token Exchange process.
You can use the service token with the Cloud Code C# Client SDKs. To use it with other APIs, you need to pass it as a bearer token in the Authentication header.
Supported services
For a list of services that support service tokens, refer to the table below:
Provider | Supported services |
---|---|
Cloud Code C# Client SDKs | Refer to Available libraries for a list of available SDKs. |
UGS Client APIs | |
Cloud Code C# Admin SDKs | Not supported. Use Service Account authentication instead. |
UGS Admin APIs | Not supported. Use Service Account authentication instead. |
Note: We are still working on the documentation for Cloud Code C# Client SDKs. For now you can refer to the JavaScript documentation as it has a similar structure. Please also make use of your IDE's auto complete and intellisense features.
Use tokens with Cloud Code C# Client SDKs
To use a ServiceToken
with the Cloud Code C# Client SDKs, pass the token from the IExecutionContext
interface.
The example below takes in a player ID and increments the balance of a currency for that player:
C#
[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId, string playerId)
{
...
try
{
// Increment the balance of the currency for the player ID passed in, authenticated as Cloud Code
var res = await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken,
ctx.ProjectId, playerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));
_logger.LogInformation("Incremented currency {currencyId} balance by {amount}", currencyId, 10);
return res;
}
catch (ApiException e)
{
_logger.LogError("Failed to increment {currencyId} balance for the player. Error: {error}", currencyId, e.Message);
throw new Exception($"Failed to increment {currencyId} balance for playerId {ctx.PlayerId}. Error: {e.Message}");
}
}
Use tokens with UGS Client APIs
To use a ServiceToken
with the UGS Client APIs, pass the token as a bearer token in the Authentication header.
Note: If the service you call provides a Cloud Code C# SDK, you can use the SDK instead of calling the service API directly. For a list of available SDKs, refer to the Available libraries page.
For example, if you define an interface for Cloud Save API, you can use the ServiceToken
to authenticate and interact with cross-player data.
The example below takes in a player ID and returns all the data stored for that player:
C#
using System.Net;
using Unity.Services.CloudCode.Core;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Authenticators;
namespace ExampleModule;
public interface ICloudSaveData
{
public Task<CloudSaveResponse?> GetData(IExecutionContext context, string playerId);
}
public class CloudSaveResponse
{
public CloudSaveItem[] Results { get; set; }
}
public class CloudSaveItem
{
public string Key { get; set; }
public object Value { get; set; }
}
public class CloudSaveData : ICloudSaveData
{
private readonly RestClient _httpClient;
public async Task<CloudSaveResponse?> GetData(IExecutionContext context, string playerId)
{
var request = new RestRequest($"v1/data/projects/{context.ProjectId}/players/{playerId}/items")
{
// Authenticate as Cloud Code to interact with cross-player data
Authenticator = new JwtAuthenticator(context.ServiceToken)
};
// Pass through the analytics user id and Unity installation id to the service.
if (context.AnalyticsUserId != null)
request = request.AddHeader("analytics-user-id", context.AnalyticsUserId);
if (context.UnityInstallationId != null)
request = request.AddHeader("unity-installation-id", context.UnityInstallationId);
RestResponse response = await _httpClient.ExecuteGetAsync(request);
if (response.Content == null)
throw new Exception("Failed to load data from Cloud Save: Content was null");
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception("Failed to load data from Cloud Save: " + response.Content);
return JsonConvert.DeserializeObject<CloudSaveResponse>(response.Content);
}
}
Note: Cloud Code provides a Cloud Save C# SDK that you can use to interact with Cloud Save data. This sample above is demonstrates how you can use the ServiceToken
to authenticate with other UGS services.