Godot WebSocketClient and HTTPRequest: enforcing least-privilege tokens and detecting expired credentials
0 reputation · 22 Oct 2023, 23:44 UTC
0 reputation · 22 Oct 2023, 23:44 UTC
I am designing the network layer for a Godot 4 project that talks to a backend over WebSocketClient and HTTPRequest, plus some high-level multiplayer RPC. I want to follow least-privilege principles: short-lived bearer tokens with narrow scopes, and a clean way to react when a token expires mid-session.
From the documentation, both WebSocketClient and HTTPRequest let me set arbitrary request headers such as Authorization: Bearer <token>, but I cannot find any built-in mechanism that detects a 401/403 response, signals token expiration, or retries with refreshed credentials. It appears the developer must inspect response codes manually and update headers in script. Similarly, the high-level multiplayer API seems to gate RPC calls only on the network authority flag, with no method-level permission scoping, so any authorization beyond that would need custom checks inside each RPC method.
My concern is doing this without introducing an infinite reconnect loop when refresh fails, and without leaking tokens into logs or remote peers. I also want to avoid a design where a compromised non-authority peer can invoke privileged RPC methods because I relied on the authority flag alone.
31775 reputation · 23 Oct 2023, 10:10 UTC
1. No engine signal for token expiry. Godot 4 exposes only the request_completed signal on HTTPRequest, which returns the HTTP status code. WebSocketClient emits closed and connection_error, but these do not distinguish a 401‑style reason from other disconnect causes. Therefore, detecting an expired bearer token requires inspecting the status code (or close code/message) yourself.
2. Least‑privilege RPC. The built‑in authority flag is the only server‑side check. To enforce fine‑grained permissions, include an ACL claim (e.g., role or scope) in the token, have the server validate it, and then expose that claim to the client. Each rpc implementation must read the claim from the authenticated session and reject calls that are not allowed. This keeps the server as the single source of truth for permissions.
3. Re‑authenticating a WebSocket. WebSocketClient sends headers only at connect_to_url. If the server closes the socket due to an expired token, the client must close the connection (or let it close) and reconnect with a new token. Re‑sending headers on an existing connection is not supported.
HTTPRequest to request a short‑lived token from your auth endpoint. Store the token in a secure, non‑logged variable.connect_to_url(url, headers), include Authorization: Bearer <token> in the headers dictionary. Do not log the dictionary or its string representation.request_completed and check if response_code == 401 or 403. If so, trigger a token refresh and reconnect.closed and parse the close code/message. If the message indicates “token expired” (e.g., a custom close code 1008), start the same refresh‑and‑reconnect flow.rpc, first check if !is_authorized(role, method) and return an error if the check fails. The client should also guard against calling privileged RPCs when not authorized.Authorization header to the console or a log file. If you need to log a request, mask the token (e.g., ***).To tailor the retry limits, could you share what maximum reconnect attempts you consider acceptable for your user experience?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.