Godot Nakama - token auth invalid after server restart

I am using Godot 3.5.3 and image: heroiclabs/nakama:3.10.0 with image: cockroachdb/cockroach:latest-v20.2, and image: prom/prometheus on windows amd64 with Docker Desktop on the side. So, I have the .bat file that I run that does all of the docker-compose -f “%~dp0docker-compose.yml” up which seems to get everything running for server in a cmd window. I have Godot set up and everything is good to go with code (so far). I can create users through registration and as long as the server is running from when I registered a user and logged in, I can find the character info.

The issue is, if I stop the server via closing the cmd window which before closing is shows everything shutting down, nakama, prometheus, cockroachdb, etc. then it closes. If I restart the boot.bat, the server starts up but if I try to log in again, I get === Nakama : DEBUG === Request 2 returned response code: 401, RPC code: 16, error: Auth token invalid.

Im guessing it never invalidates the ticket or something? I dont know what to do with that. I have searched topics and some are ‘similar’ but I couldnt figure it out yet. I found out that it could be the token still active for some reason.

  1. Versions: Nakama {3.20.1}, {Windows, Docker}
  2. I have GO installed but I have no idea if it uses it or not.

I think this is where some of the issue triggers on the else: _ws.poll().

func _process(delta):
	if _ws.get_connection_status() == WebSocketClient.CONNECTION_CONNECTING:
		if _start + _timeout < OS.get_unix_time():
			logger.debug("Timeout when connecting to socket")
			emit_signal("received_error", ERR_TIMEOUT)
			_ws.disconnect_from_host()
		else:
			_ws.poll()
	if _ws.get_connection_status() != WebSocketClient.CONNECTION_DISCONNECTED:
		_ws.poll()

This is the last message in the cmd so that looks ok I guess: nakama-1 | {“level”:“info”,“ts”:“2024-02-11T16:47:21.732Z”,“caller”:“main.go:175”,“msg”:“Startup done”}

If I delete the user in the Nakama Console (127.0.0.1:port), I can re-register and it works the first time but I cant shut down the server otherwise it does the error if I start it back up. Thanks if you can help. There is another issue afterwards where I cant join the world but Ill leave that for another topic if I cant get that to work. It worked yesterday and I didnt change ANY code from when I woke up and started testing again. This was all the sudden.

NOTE: I did follow the tutorials both from GDQuest and from your Youtube, they were over an hour videos of setting everything up. :stuck_out_tongue: Thats my reference.

Hey @mojoyup1528 there are two tokens – an auth (short-lived) and a refresh token (long-lived). The refresh token and a fresh auth token are obtained on authentication. The Godot client will automatically refresh the auth token when its close to expiring. But you’ll still need to check is_refresh_expired on your session and reauthenticate when the refresh token is close to expiring.

1 Like

You should also make sure you are on Release - v3.18.0 or greater of the Nakama server and that you’ve set your token expiry times to suitable timeframes. See our configuration here:

1 Like

Good idea, yes I verified that I am using 3.20+ :slight_smile: Though I havent messed yet with expiration times and I know that is a push on developers to pay attention to that ;). Ill find it and play around with the timing!

Its been a bit sorry, just was able to get back to a project. I am having similar issues now for logging out of a session. The logging in and authentication works great now (with the exception of getting user account information[another topic I guess]). But for logging in I have this:


func authenticate_user_login_async(email, password) -> int:
	var token = recover_session_token(email, password)
	if token != '':
		print('TOKEN:::::', token)
		var new_session = client.restore_session(token)
		if new_session.valid and !new_session.expired:
			session = new_session
			yield(Engine.get_main_loop(), "idle_frame")
			return OK
	else:
		print('TOKEN NOT AVAILABLE')
	var new_session = yield(client.authenticate_email_async(email, password, null, false), 'completed')
	var result = parse_exception(new_session)
	if result == OK:
		session = new_session
		write_auth_token(email, session.token, password)
	return result

and for the parse_exception() Im using this:

func parse_exception(result) -> int:
	if result.is_exception():
		var exception = result.get_exception()
		error_message = exception.message

		return exception.status_code
	else:
		return OK

Seems like it would be ok. It does save an ‘AUTH’ file in my user:// in the appdata which is good. But when I try to log out using this:

extends Button


func _on_log_out_btn_button_up():

	var logout = yield(ServerConnection.client.session_logout_async(ServerConnection.session), 'completed')
	
	if logout.is_exception():
		print('Could not log out, try again!')
	else:
		print('Logging out...')
		#EXECUTE SAVING ALL THE INFOMATION FIRST, THEN CALL
		
		get_tree().notification(MainLoop.NOTIFICATION_WM_QUIT_REQUEST)

I get an error that says:

=== Nakama : DEBUG === Request 1 returned response code: 401, RPC code: 16, error: Auth token invalid
Could not log out, try again!. I figured it was relevant due to the “Auth token invalid” part. I know you mentioned there are two tokens, one for auth and one for refresh. Sorry I just am trying really hard to figure all of this out on my own. Ive been able to get nearly nowhere. Maybe its not for me but I absolutely love doing this stuff. IDK This is also in the engine that shows the session:

Hey @mojoyup1528 it sounds like your session is expiring mid-game because we default to a very short session time in order to force you to set it yourself. Take a look at our docs on session lifetime on how to change this value: