Authenticating users

Started by
27 comments, last by Sergey Ignatchenko 8 years, 1 month ago

I'm currently building a UDP server that my game will talk to. The users will need to have an account created, either by using a Single Sign-On account such as Facebook or Google, or by creating an account. I'd then like them to link their account to the platform specific gaming services such as Game Center.

When the client first starts up and sends a request to the server, what would be the best way to authenticate the user? I can create them an account and store their account on the server but how do I authenticate them each time afterwards? I'm simi-familiar with using OAuth for web-services and was wondering if the server and client should both store the token generated by the OAuth process, having the client send the token to my server for authentication and validation? Should I include that token with every packet sent to the server from the client so I know they are who they say that are?

Is this to much of a "RESTful" approach and not how most other games handle authentication?

Advertisement
I think most mobile games do it the other way around -- you sign into Game Center, or Google Play, and it authenticates for you and tells you the user's ID.

Other options depends on whether you are in a browser (so you can include oauth flows and store cookies) or if you're native (so you can store files, but can't easily do a typical oauth flow.)
enum Bool { True, False, FileNotFound };

I would like to associate the mobile SDK services with the users accounts, but want an account independent of Game Center/Google Play so that I can sync player data across platforms.

Maybe the easiest thing to do is integrate with the native SDK services first and then provide the option to create an account for syncing. At which point I can handle through my server and not interact with OAuth providers at all. I know as a gamer I prefer to just use my existing accounts when I can though, one less password to remember.

You also need to consider transport security as well as authentication, if you aren't relying on the native SDK to handle everything.

If you are implementing this over UDP, then you are in the wonderful world of DTLS, which is a whole other can or worms.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Do you guys have any material I could read up on for using TLS/DTLS? I've never had to use any TLS/HTTPS protocols before so I'm not sure what processes there are for generating a certificate, or if I even have to generate a certificate for DTLS.

If I do have to use a certificate, do I have to send it across the wire in both directions during transmission of each Datagram so the server and client know they are always talking to the proper authority?

For a game, you have to consider whether there really is anything to protect.
If you send passwords, then perhaps there is.
If I remember correctly, what you want to do is a Diffie-Hellman key exchange to set up a key pair, then use that to exchange a symmetric, randomly generated session key (for AES, AES-256, or similar,) then send a random nonce/IV at the head of each packet.
With AES-256, that's 32 bytes extra payload per UDP datagram, which can add some weight, depending on your specifics. (Or it's "free" because of packetization in networks.)

If you can find a good DTLS library, or use the built-in services on the platform, you save a bunch of work.
enum Bool { True, False, FileNotFound };


For a game, you have to consider whether there really is anything to protect.
If you send passwords, then perhaps there is.

How else is someone going to authenticate, other than providing a token proving identity (password, OAuth federation token, etc)?

Especially in the age of in-game currency and other freemium items, stealing accounts for popular games is big business. Neglecting security on the basis that your agem will never be popular enough to matter is a viable choice, but not necessarily a wise one.


If you can find a good DTLS library, or use the built-in services on the platform, you save a bunch of work.

Don't monkey around doing this yourself. Security is easy to get wrong. Use OpenSSL, or your platform's equivalent.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Use OpenSSL, or your platform's equivalent.


"SSL" doesn't work on UDP, though, which is what we're talking about here.
DTLS is the moral equivalent for UDP.
Some SSL libraries do support DTLS options. There are also a few DTLS-only libraries.

In general, over UDP, you can't just use a stream cipher, because each individual PDU may be dropped or re-ordered.
Hence, some kind of nonce/IV needs to be part of each separate UDP packet. (DTLS seems to just use sequence number, which seems less secure than a strong random per PDU)

https://tools.ietf.org/html/rfc6347
enum Bool { True, False, FileNotFound };


"SSL" doesn't work on UDP, though, which is what we're talking about here.
DTLS is the moral equivalent for UDP.
Some SSL libraries do support DTLS options. There are also a few DTLS-only libraries.

OpenSSL is one of those. They've supported DTLS since versions 0.9.8 or thereabouts.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Do you have a link for the DTLS support in OpenSSL? I have not been able to find much on that when googling :/.

Using SSL for communicating with the server seems like a large amount of overhead once the client is authenticated. When the client is authenticated, as long as I map the PlayerId from my database with the IP that the user is authenticated with, can I send any non-sensitive data (like location updates and chat messages) over as plain text to the authenticated IP? Is there a performance overhead by sending every packet through SSL?

This topic is closed to new replies.

Advertisement