heroiclabs / nakama

Distributed server for social and realtime games and apps.
https://heroiclabs.com
Apache License 2.0
8.84k stars 1.08k forks source link

Add session variables that are available throughout the server code #294

Closed gupta-vaibhav closed 4 years ago

gupta-vaibhav commented 5 years ago

This is more of an enhancement / feature request than an issue / bug.

We would like to be able to add session variables that are attached to a user's session and are readily available to the server side throughout the code. This would help us in conducting A/B tests by identifying a user's cohort, which would be available as a session variable. Further, this will also help us customise the user experience base on, say, location / cohort / etc.

novabyte commented 5 years ago

@gupta-vaibhav do you have some examples of the kind of key/value pairs you could see be useful as session variables?

I like the plan for this feature but I'd like to discuss the options for integration. As far as I can see there's a few different ways to make this possible:

Each approach above has small advantages and disadvantages as with all feature design. :)

In all cases I believe the best way to introduce these kinds of session variables is to have them live in the session token. Any other approach introduces additional database operations on the critical path of authentication which we cannot do. We have games that operate at huge scale and cannot suffer for the overhead which would be introduced with additional database work.

The client libraries could read the values out of the session token (JWT) so they can be utilized within client code and they'd be available in the context object to RPC functions, etc as normal in the server.

/cc @zyro

gupta-vaibhav commented 5 years ago

Chris,

Absolutely agree, the way to do it would be through the session token. If we had to do it via database queries, we already have the option to create user storage objects that can be read / written freely. :)

Firstly, to answer your question, I can think of several key value pairs that we have used in the past: Provided by the client

With regards to the options laid out by you, in my opinion: First preference should be the second option, i.e. extra options to the before hook, simply because in theory the session vars could also vary depending upon the type of authentication. In case they are the same for all the auth methods, before hook could simply call a common function to update these variables.

Second preference would be for a special hook into the authentication phase. This option as well as the previous one, will also eliminate the chances of error that may caused by requesting user specific data before setting the session vars.

Last preference would be for the third option, i.e. separate function to decorate the session token, for the reasons that - a) it is an additional overhead on the client, b) it is an additional network request, c) leaves in room for error, i.e. calling functions before setting session variables.

Those would be my 2 cents.

zyro commented 5 years ago

I like the idea of allowing both info from the client (such as platform) as well as server authoritative info (such as VIP status).

Most straightforward seems to be allowing some KV input in the authentication calls, so a before hook could validate and ensure clients don't set sensitive parameters when they shouldn't be allowed. There's an edge case here where server validation could be performed (like looking up a user's VIP status) but the authentication later fails - it's not an error case as such, just an area where we might do extra work that we don't need. A special hook that fires only on successful authentication is the only way to solve this that I can think of right now.

This data would then be read out of the session token and made available to hooks, RPC functions, and other server-side contexts where the session might be exposed. I agree with the client parsing these values out of the session but I don't think they need to be implicitly exposed to other users by attaching this data to every presence, for example.

gupta-vaibhav commented 5 years ago

@zyro, my bad if I am missing something basic here. Why would we need a special hook after authentication and not do it in the currently provided after hooks for authentication?

I agree that these need to be exposed only through the session token to the server side contexts of the user. These should not be exposed to other users by attaching this data to every presence (of the match, I suppose?).

novabyte commented 4 years ago

Session variables was added in the 2.7.0 release of Nakama. A map of key/value strings can be passed into the authenticate functions to be set in the session token or the authenticate flow can be decorated in a before hook to add these parameters into the token.

They can then be read from the context object in server-side function calls or on the client-side in the session object code (varies based on the client sdk).