Authenticate a user with Satori

When looking at the docs for how to authenticate:

userId := "user-id"
satoriIdentity, err := satori.Authenticate(ctx, userId)

But the API in Nakama 3.16 is:

*
Satori runtime integration defintions.
*/
type Satori interface {
	Authenticate(ctx context.Context, id string) error
	PropertiesGet(ctx context.Context, id string) (*Properties, error)
	PropertiesUpdate(ctx context.Context, id string, properties *PropertiesUpdate) error
	EventsPublish(ctx context.Context, id string, events []*Event) error
	ExperimentsList(ctx context.Context, id string, names ...string) (*ExperimentList, error)
	FlagsList(ctx context.Context, id string, names ...string) (*FlagList, error)
	LiveEventsList(ctx context.Context, id string, names ...string) (*LiveEventList, error)
}

The Authenticate() function does not return a Satori identity for the user. Has the idea of a custom id been removed and everything just uses the normal Nakama user id?

The documentation is incorrect, the function does not return an Identity, we’ll fix it shortly.

Authenticate() won’t return an identity, but it’ll create one in Satori (if one does not exist yet) tied to the used identifier (id) param.

If an identity already existed, Authenticate() is effectively a noop.

Once the Satori identity exists, id can reliably be used to identify that identity across API calls.

You can use the Nakama userID but it’s not enforced, you may use whatever other valid identifier makes sense for you to track an identity on Satori.

Thank you for the clarification. So the id to Authenticate(ctx context.Context, id string) can be anything, but in our case users all use the one assigned by Nakama. So I would call Authenticate for every single user that connects to the server, or would I do it only once for the entire server and use some random id? Publishing events etc seem to use some id referencing a user, is this id different from the one given in Authenticate(ctx context.Context, id string)? Things that we’d want to track are specific to users, so my guess is that the id in, say, EventsPublish(ctx context.Context, id string, events []*Event) error would be the user’s id?

Since you plan on using the Nakama user_id as the identifier, you’d call Authenticate using said id at least once for every single user, and also use the same user_id as the id param for any other Satori API calls related to that same user, such as EventsPublish as you correctly state.

The documentation has been corrected regarding the Authenticate() function.

I only wrote that I’d use the user id with Authenticate() as the docs implied it. I’m not sure really what id should be used there. Does every user need to be authenticated with Satori or is it enough to do it once with some kind of “server id” and then just submit events and other data through that? Some real examples in the docs would be nice, now they are a bit shallow.

What we really want to do is gather various metrics about what users do, A/B testing etc, just the stuff Satori was created to solve. Maybe your intention really is that the game clients should do all the analytics reporting and that the Nakama server should not really do anything? A bit confused here.

The id is whatever identifier you want to use to uniquely identify a user identity, it can be the Nakama user_id or another external identifier that you may have in place. Authenticate() call is what will create the identity in Satori and tie that identity to the id of your choice, which should then be used for every call related to that user identity to emit events, update its properties, etc.

Usually, metrics and events are emitted from the client, but you may want to read the properties of an user identity from the server to, for example, change some content based on an experiment or feature-flag some feature.

You can drive the identity creation with Authenticate()from either the client or the server or both, as long as the same id is used consistently, it doesn’t matter, the first call will create it and any subsequent ones will become noops.

Hope this clarifies, we’ll continuously work on the documentation to improve it.

Indeed it does clarify, thank you. We had the idea that some important events, like purchases, awarded rewards etc would be reported by the server as it’s more reliable. Who knows that the players actually do with their clients. :slight_smile:

I take from this that the authentication is not a heavy operation and is suitable to do for each user when he/she authenticates with Nakama? I also see no reason to not use Nakama’s own user id for the Satori authentication, makes things a lot cleaner.

Yep can absolutely emit purchase related events from the server :+1:.

Also yes, you can create a Satori identity whenever a user authenticates with Nakama and use the Nakama user_id as an identifier.

One of the reasons why we allow semi-arbitrary ids is because Satori is a standalone product, and as such it may be used with other identity providers outside of Nakama.

Another one is to allow the collection of events (from the client) even before the user has authenticated. A temporary identifier based on, for example. some local device id can be used up until the user authenticates, and then through the identifyAsync function, this temporary id would be replaced by Nakama’s user_id.