Login handshake - rebaserHEAD/NexusForever GitHub Wiki
How the client gets from a password to a character in the world: three servers, two tokens handed from one to the next, and where each step lives. Read from the code, and seen working on a local server.
The client talks to three servers in turn, and each hop hands it what the next one asks for.
sequenceDiagram
participant C as Client
participant S as STS
participant A as Auth
participant W as World
C->>S: email, password proof
S-->>C: game token
C->>A: game token
A-->>C: session key, realm address
C->>W: session key
W-->>C: realm and character lists
- STS proves the password and issues a game token.
- Auth takes the game token, picks a realm, and issues a session key along with that realm's address.
- World takes the session key, and from then on the client is in the game: realm list, character list, character select, and into a map.
| Term | Meaning |
|---|---|
| SRP6 | The password check. The client proves it knows the password without sending it; the server stores only a salt and a verifier |
| Game token | A GUID the STS server writes to the account's gameToken column. The auth server looks the account up by it |
| Session key | 16 random bytes the auth server writes to the account's sessionKey column. The world server looks the account up by it, and it also keys the world connection's encryption |
| Realm | A world server the client can pick. Each one is a row of the auth database's server table |
The two columns are also described on upstream's database documentation.
The STS server speaks a text protocol, STS/1.0: a request line naming a path, a couple of headers, and an XML body.
- The client connects and starts the login with its email. The server looks the account up, sets up SRP6 from the stored salt and verifier, and sends back its half of the exchange.
- The client answers with its own half and its proof. The server checks the proof, sends its own, and from there both sides encrypt the connection.
- The client asks for a game token. The server writes a new GUID to the account and sends it.
The auth server speaks the game's binary protocol, the same framing as the world server.
- It greets the client, and the client answers with its build number, email and game token.
- The server refuses any build but 16042, looks the account up by email and game token, and checks for bans and suspensions.
- It picks the first realm that's online, generates a session key, writes it to the account, and sends it with the realm's name, address and port.
- The world server greets the client, and the client answers with its session key.
- The server looks the account up by the session key, loads it, and switches the connection's encryption to a key derived from the session key.
- The client asks for the realm list and the character list. The character list comes straight from the character database, with the account's currencies, unlocks and entitlements alongside.
- From character select the client enters a map, and the game begins.
Switching realm from the realm list repeats the last hop: the world server issues a new session key and tells the client where to go.
| Knob | Where | Effect |
|---|---|---|
| The realm's address |
host and port of the realm's row in the auth database's server table |
Where the auth server sends the client. The seeded row is 127.0.0.1 and 24000, which only works for a client on the same machine |
Realm:RealmId |
WorldServer.json, or the Aspire host |
Which server row this world server is. It must exist, or the world server won't start |
| The account's role | account create <email> <password> <role> |
Doesn't affect logging in, but without one the account can't use commands |
| Piece | Path |
|---|---|
| STS login and game token | Source/NexusForever.StsServer/Network/Message/Handler/AuthenticationHandler.cs |
| SRP6 |
Source/NexusForever.Cryptography/Srp6Provider.cs, with the verifier made by PasswordProvider.cs beside it |
| Auth hello, realm pick and session key | Source/NexusForever.AuthServer/Network/Message/Handler/HelloAuthHandler.cs |
| The realm list behind it | Source/NexusForever.Game/Server/ServerManager.cs |
| World hello and session key | Source/NexusForever.WorldServer/Network/Message/Handler/Authentication/ClientHelloRealmHandler.cs |
| Packet encryption | Source/NexusForever.Cryptography/PacketCrypt.cs |
| Realm switching | Source/NexusForever.WorldServer/Network/Message/Handler/Character/ClientSelectRealmHandler.cs |