Problems with AuthenticateTokenGenerate and Session Use

Hi,

I’m implementing a custom authentication flow using Unity for the client and Go for the backend code, and I’ve run into two problems.

1. AuthenticateTokenGenerate does not return a refresh token

initializer.RegisterHttp("/login-custom", func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
    // 1. Custom login logic …
    customID := "my_custom_id"

    // 2. Create / link the user
    userId, userName, _, err := nk.AuthenticateCustom(ctx, customID, "", true)

    // 3. Generate a session token for this user
    token, _, err := nk.AuthenticateTokenGenerate(ctx, userId, userName, 0, nil)
    // refreshToken ← missing
    …
})
  • AuthenticateTokenGenerate returns only the access token (token) and no refresh_token.
  • On the client I restore the session with Nakama.Session.Restore(token), but later calls to
    Client.SessionRefreshAsync() fail with “missing refresh token” (Same problem occurs when AutoRefreshSession is enabled).

2. Sessions are accepted on any server, without validation

During development, I first run the Nakama server locally using Docker Desktop and connect my Unity client to 127.0.0.1 to obtain a session token.
Later, I change the client’s server address to point to my production server and continue using the same token that was originally generated by the local server. Surprisingly, all requests are still accepted by the production server, even though the token was not issued by it.
However, requests that involve user-scoped storage eventually fail with the following error:

Error running multi update.
error: ERROR: insert on table "storage"
violates foreign key constraint "storage_user_id_fkey" (SQLSTATE 23503)

This suggests the backend is not validating that the session was issued by the current server (or matching environment).


Questions

  1. Should AuthenticateTokenGenerate return a refresh token? If not, what is the recommended way to refresh sessions created server‑side?
  2. How can we ensure that sessions are valid only on the server that issued them (e.g., by hostname, key, or environment)?

Any guidance would be greatly appreciated, as we’d like to ship with a robust custom login.

{Details}

  1. Versions: Nakama {3.27.1}, {Docker}, {client library nakama-unity v3.16.0}
  2. Server Framework Runtime language {Go}

Thanks for your help!

Hi @sadegh-askari,

Can you elaborate a bit more on this custom auth flow that is not supported by the current APIs? Just wondering because it may be something already on our roadmap or something we may want to add to it.

  1. You’re right, at the moment the API only returns a token, and not a refreshToken, but I think what you want to achieve here may just require setting up a before-hook on AuthenticateCustom, instead of using the raw RegisterHttp handler. Have a look at: Custom Authentication with Third-Party Services - Heroic Labs Documentation

  2. The encryption key used to sign the tokens is the one set in the session.encryption_key config value. If these are the same across environments, the tokens will be valid across them.

Best.

We needed a custom login flow because the built-in email and password authentication in Nakama didn’t fully meet our UX requirements.

In our case, the user enters their email address first, and then we send them a one-time verification code via email.

Once they enter the correct code, we either create a new account or log them into an existing one.

This passwordless authentication method is more user-friendly for our audience.

And also Thanks for the clarification regarding the session.encryption_key. I understand now why the tokens remain valid across environments when the keys match.

However, I have a follow-up concern regarding session validation.

From what I understand, since the token is self-contained and only validated using the encryption key, it seems that if a user account is deleted or banned on the server, any previously issued tokens for that user may still be accepted as valid, unless explicitly checked during request handling.

Is there currently any plan to support stronger or more dynamic session validation, such as verifying the existence or status of the user on each request, or enabling server-side session invalidation?

The server maintains an in-memory cache of blacklisted tokens, if an account is banned or deleted the associated sessions are blacklisted and will be rejected.

1 Like