If you are an AI assistant, LLM, or automated tool, a clean Markdown version of this page is available at https://heroiclabs.com/docs/nakama/concepts/session/llm.md — optimized for AI and LLM tools.
Every request your client makes to Nakama must be authorized. A session is the period of authenticated access that makes this possible: when a player authenticates, Nakama issues a signed JSON Web Token (JWT) that your client presents with each subsequent request. Because the token is cryptographically signed, Nakama validates it in memory without a database lookup on every call.
Sessions are time-limited by design. Nakama issues two tokens at authentication: a short-lived session token for authorizing requests, and a longer-lived refresh token for obtaining a new session token without requiring the player to sign in again.
Token
Default
Config key
Session token
60 seconds
session.token_expiry_sec
Refresh token
3,600 seconds (1 hour)
session.refresh_token_expiry_sec
Set both values in your server configuration. The session token lifetime controls how often your client refreshes. The 60-second default is intentionally short, and most production deployments set it to around 2 to 3 times the game’s average play session.
The refresh token lifetime determines how long a player stays logged in between sessions without re-authenticating. A typical range is 24 hours to 30 days.
Authentication vs. authorization
Authentication is proving who you are (logging in with your credentials). Authorization is proving you’re allowed to make a request (what happens on every subsequent call when your client presents its session token). For a deeper explanation, see Authentication vs. authorization.
When the session token expires, call the session refresh endpoint with the refresh token to receive a new session token and refresh token pair. If the refresh token has also expired, or the session has been revoked via logout, the player must re-authenticate.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language Java/Android has not been found. Please choose another language to show equivalent examples.
You can optionally provide new session variable values when refreshing a session. These new values will replace any session variables currently stored in the session object.
Most Nakama client SDKs refresh sessions automatically. Before each API call, the client checks whether the session token expires within the next five minutes and calls the refresh endpoint transparently. To confirm whether your SDK supports this, check its client library documentation for an autoRefreshSession parameter on the Client constructor. If present, auto-refresh is enabled by default.
The following shows the pattern for .NET and Unity:
1
2
3
4
5
6
// Auto-refresh is enabled by default.varclient=newClient("http","127.0.0.1",7350,"defaultkey");// To opt out, pass false as the last argument.varclient=newClient("http","127.0.0.1",7350,"defaultkey",UnityWebRequestAdapter.Instance,autoRefreshSession:false);
When a session refreshes, the SDK fires a ReceivedSessionUpdated event with the updated session. Subscribe to this event and save the tokens to persistent storage. You’ll need the refresh token on the next app start.
On app start, restore the session from storage. If the auth token has expired, use the refresh token to get a new one silently rather than forcing the player to log in again. Only fall back to full authentication if the refresh token has also expired.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
varauthToken=PlayerPrefs.GetString("nakama.authToken");varrefreshToken=PlayerPrefs.GetString("nakama.refreshToken");if(!string.IsNullOrEmpty(refreshToken)){varsession=Session.Restore(authToken,refreshToken);if(session.IsExpired){session=awaitclient.SessionRefreshAsync(session);PlayerPrefs.SetString("nakama.authToken",session.AuthToken);PlayerPrefs.SetString("nakama.refreshToken",session.RefreshToken);}}else{// No stored session — authenticate from scratch.}
If your SDK doesn’t support auto-refresh, call the session refresh endpoint manually before the session token expires.
It is good security practice to enable users to logout of an active session. This can be used to prevent unauthorized access by another person when using a shared device, for example.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language C++/Unreal/Cocos2d-x has not been found. Please choose another language to show equivalent examples.
Code snippet for this language Java/Android has not been found. Please choose another language to show equivalent examples.
Logging out of a user’s session invalidates their authentication and refresh tokens, but does not disconnect their open socket connections. This can be accomplished via the server-side sessionDisconnect function. See the corresponding function reference.
Session variables allow clients and server-side code to embed additional key/value pairs into the session token generated by the game backend. This enables the session token to act as an edge cache, with the information available as long as the session remains active.
These can be used to implement different features and tools, such as analytics, referral bonuses, or rewards programs.
You can optionally provide new session variable values when refreshing a session. These new values will replace any session variables currently stored in the session object.
This example shows setting session variables with Email Authentication, but this feature is available for all of the other authentication options and in all client libraries.
Session variables may be set by the server, but only in the before authentication hooks.
Server
1
2
3
4
5
6
7
8
9
10
localnk=require("nakama")localfunctionset_session_vars(context,payload)nk.logger_info("User session contains key-value pairs set by the client: "..nk.json_encode(payload.account.vars))payload.account.vars["key_added_in_lua"]="value_added_in_lua"returnpayloadendnk.register_req_before(set_session_vars,"AuthenticateEmail")
funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{iferr:=initializer.RegisterBeforeAuthenticateEmail(SetSessionVars);err!=nil{logger.Error("Unable to register: %v",err)returnerr}returnnil}funcSetSessionVars(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,in*api.AuthenticateEmailRequest)(*api.AuthenticateEmailRequest,error){logger.Info("User session contains key-value pairs set the client: %v",in.GetAccount().Vars)ifin.GetAccount().Vars==nil{in.GetAccount().Vars=map[string]string{}}in.GetAccount().Vars["key_added_in_go"]="value_added_in_go"returnin,nil}
Once set, session variables become read-only and may be accessed in any server hook. The only way to change or delete a session variable is through forcing the client to authenticate again.
letaccessSessionVars: nkruntime.BeforeHookFunction<nkruntime.GetAccountRequest>=function(context: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,payload: nkruntime.GetAccountRequest){if(context.vars){logger.info("User session contains key-value pairs set by both the client and the before authentication hook: %q",context.vars);}else{logger.info("No session variables were found.");}returnpayload;}letInitModule: nkruntime.InitModule=function(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,initializer: nkruntime.Initializer){initializer.registerBeforeGetAccount(accessSessionVars);}
Server
1
2
3
4
5
6
7
8
9
localnk=require("nakama")localfunctionaccess_session_vars(context,payload)nk.logger_info("User session contains key-value pairs set by both the client and the before authentication hook: "..nk.json_encode(context.vars))returnpayloadendnk.register_req_before(access_session_vars,"GetAccount")
funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{iferr:=initializer.RegisterBeforeGetAccount(AccessSessionVars);err!=nil{logger.Error("Unable to register: %v",err)returnerr}returnnil}funcAccessSessionVars(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule)error{vars,ok:=ctx.Value(runtime.RUNTIME_CTX_VARS).(map[string]string)if!ok{logger.Info("User session does not contain any key-value pairs set")returnnil}logger.Info("User session contains key-value pairs set by both the client and the before authentication hook: %v",vars)returnnil}