I'm building a poker like game server, I was going to have all logins and game logic to be handled on one server, but from my research on the web, I learn that this would not scale, and it would make sense to split the work into a login and game servers. But what I don't get is after I handled authentication in the login server, and have the client make a new connection to the game server, how would I know which client is which? Would I not have to re-login again and thus defeat the purpose of having a server for login? Is there some way to pass a connection across processes and machines that I don't know about? Excuse my little knowledge of networking.
Although Philipp's answer is perfectly good, there is a slightly different way that does not require a connection between the login server and the game server, which is useful if such a connection is difficult.
- When the user authenticates successfully on the login server, they are sent a game server address and a login token as above. However this token consists of 2 parts: the time on the login server, and a hash of that number plus their username, their IP address, the IP address or ID of the game server, and a secret key that only you know.
- The client attempts to log in to the provided game server by sending this token. The server forms the same hash as before, based on the information in the login token plus its own IP address/ID and the secret key. If this hash matches the one in the token, you know the player authenticated properly. Then check the date is not too old (eg. more than 1 minute).
This works because:
- It can't be copied and re-used as the date will expire.
- It can't be constructed without a fresh login without knowing the secret key.
- It can't easily be intercepted by someone else (eg. with a packet sniffer) and used because the original IP address is used to construct it.
- It can't be used for a different account as the username forms part of the hash.
- It can't be used for concurrent logins on different game servers as the server's ID/IP address forms part of the hash.
Or to put it more simply, the hash ensures that it's nearly impossible for the sender to have forged their login token and so the information in the token can be trusted.
As with any security oriented hashing, use the best hash function you can get - at the moment people seem to like bcrypt, PBKDF2, and scrypt - and ensure your secret key is very long so as to make brute force reproduction less practical.
After the user authenticated itself to the loginserver, give it a token (an unique, randomly-generated string too long to be guessed).
The loginserver picks a gameserver. Send the token, the username and all other relevant data about the user from the loginserver to the server it picked.
Send the token and the hostname of the gameserver to the client. Then disconnect it from the loginserver.
The client then connects to the gameserver with its username and token.
When the token from the client matches the one just reported by the loginserver, you accept it.
Note that in order for this to be secure, the tokens need to be created from a cryptographically secure random number generator, each token may only be accepted once by the gameserver and unused tokens should be discarded after a few minutes.