Extending nakama source code

Hi there!

I’m trying to integrate Redis in our custom version of nakama, but I realized the lua client probably won’t work because it has some dependencies with luasockets and since nakama is using a custom version of lua (gopher-lua) I’ll have to use gluasocket.

My question is. How do I add new gopher-lua modules?
And do you think guys integrate Redis with nakama is possible or I’m just wasting time?

Thanks in advance.

Hi @danim. You wouldn’t be able to integrate Redis with Lua. Although you may be able to do it through a Go module as a custom plugin to Nakama. I must say that this is non-trivial though.

Nakama has various built-in caches for different APIs. I’m wondering why do you need Redis at all?

I am also interested in integrating Redis into Nakama. My goal is to validate the session that gets generated by the Authenticate*() functions during all RPC calls while the session remains active. Rather than send the player’s username and password with every RPC call, it would be more secure to instead pass the session object to the RPC. That session, along with the player info, would be written to an in-memory cache to avoid the database reads and writes needed to refresh the volatile session objects.

If Redis is not a viable solution here, is there another way to validate a session without constantly hitting the database?

@jamesbaud Sessions are already validated without a query to the database? We use JWTs to achieve this behaviour. I’m confused about this point as well:

Rather than send the player’s username and password with every RPC call,

This does not happen in Nakama. All of the client SDKs already offer an RPC function call which can be executed to interact with the authenticated player session. This passes the session token into the API call.

As far as I can tell you don’t need Redis at all for any of your game design but perhaps there’s some details I’ve missed from your post?

I guess then I am confused with how sessions are validated. I launch a Nakama and CockroachDB instance in Docker and connect to it in Unity. The timeout on the session is 60 seconds, the default in Nakama. Then, behind the scenes I tear down the Nakama and CockroachDB instance entirely and rebuild completely new ones within that 60 second timeout. When I launch the Unity app, it connects to the brand new Nakama and CockroachDB instance without issue, using the old session that was created with the old instances of Nakama and CockroachDB. If I completely destroyed the old instances and rebuilt new ones, how is this new session valid?

Rather than send the player’s username and password with every RPC call

I was suggesting here that if I could not validate the session on the server, I would instead need to send the player’s username and password with every RPC call so I could verify that the request made by the player is indeed legit. For example, I want to be certain that if a player makes a request to purchase some sort of item, that the request is coming from the player and not being spoofed by another user. Validating the session or passing the player’s username and password are the two straightforward options I see in order to achieve this.

Any insight would be helpful. Thanks!

Nakama uses JSON Web Tokens as session tokens to identify users after authentication. They’re a standard for stateless, cryptographically signed identity tokens and you can read up on how they work in the RFC.

Just to stress this: you don’t need to send the username/password/anything else with every request to be able to identify the user - aside from the session token itself of course. In your case RPC functions expose a context where you can extract information about the user that has called this function, and trust that the server has already validated those values.

If I understand correctly, the JSON Web Token is created using a secret key from the client. Nakama never stores this token, which is why it remains valid between server restarts, but it is able to validate it because the JWT is entirely self-contained.

In order for this to work, it needs to create the JWT using a secret key. On iOS with Game Center as the authentication method, I would imagine that it uses the local player identifier as this secret key instead of the unique device ID so that a player can switch devices and still retain their progress. But this would mean that if a hacker were to get a hold of that public player identifier, which is easily accessible through Game Center, they would be able to send messages on behalf of that player.

So my question is, “What does Nakama use as the secret key on iOS devices to prevent hackers from sending messages on behalf of someone else?”

If I understand correctly, the JSON Web Token is created using a secret key from the client.

The key in JWT terminology is usually called the signing key. You can set it to custom value with Nakama at startup either through the YML file or cmdflags:

--session.encryption_key <someval>

When this value is changed it will cause the server to invalidate all existing tokens (requiring users to reauthenticate with the server). This is all standard with how JWT-based sessions work.

On iOS with Game Center as the authentication method, I would imagine that it uses the local player identifier as this secret key instead of the unique device ID so that a player can switch devices and still retain their progress. But this would mean that if a hacker were to get a hold of that public player identifier, which is easily accessible through Game Center, they would be able to send messages on behalf of that player.

Sorry I have no idea where this has come from. When you authenticate with Game Center we do a server-side call to Apple’s Game Center to exchange the value given back by Apple for a user account. We then create a new user account (or link to an existing account) and return a JWT session token. No where can the hacker “get hold of the public player identity” from Game Center. Have a look at the docs for how authentication works:

https://heroiclabs.com/docs/authentication/

So my question is, “What does Nakama use as the secret key on iOS devices to prevent hackers from sending messages on behalf of someone else?”

We don’t use a “secret key on iOS” we simply receive a token from Game Center and exchange it on the server for the player profile. This follows all the guidelines provided by Apple on how these services should work. This may all change now that Apple has launched their own sign-in service with iOS 13 but you can follow progress on that with this issue.

The code for how we authenticate with Game Center is all open-source. You can read the relevant code here:

This post has drifted far off topic from the original question. I’ll lock it and @jamesbaud please open a new issue to discuss Game Center authentication in more detail if needed.