Building a Multiplayer Backend: Authentication

Here at Wolfjaw Studios, we build game backends for a living. Over the last 5 years we have built partnerships with amazing publishers and studios. We have had the opportunity to work on titles like NBA2K, Destiny 2, League of Legends, Among Us, Apex Legends, and several unannounced titles. For more information about who we are, you can read The Story of Wolfjaw Studios and Raising the Bar with Catena Tools.

This article is the first in a series where we will discuss some of the basics of building out a multiplayer backend. There are many components which all must work together in tandem to provide first-class multiplayer experiences to players. While every game is unique, some of the basic components of their online services remain similar. Online services can mean different things to different people. To us at Wolfjaw, we define them as the following non-exhaustive list:

  • Authentication, Authorization, and Accounts
  • Entitlements
  • Inventory and Progression
  • Matchmaking and Fleet Management
  • Leaderboards
  • Social Features: Friends, Parties, Presence
  • Reporting, Banning, and Player Moderation
  • Telemetry

Through this series, we will distill down the expertise we’ve accumulated by working on some of the biggest online games in the world to demystify the process of building a multiplayer backend that is feature rich, resilient, reliable, and ultimately meets the needs of your game. We will discuss the trade-offs of different approaches and equip you with the toolset to make smart decisions, setting your game up for success.

The Foundation For All Game Backends, Authentication and Accounts

Authentication, authorization, and accounts are the core components of any account system, but the differences between them can often be confusing.

Authentication refers to the verification of the identity of a player. For example, when you authenticate you prove that you are in-fact, you. If we have a player named Bob, our authentication system will help us prove that Bob is Bob. We do this by checking his credentials and providing Bob with an identifier in our system.

Authorization on the other hand refers to verifying and restricting access within the system. It determines what a player is and is not allowed to do. For example, if Bob has purchased the DLC of a game he may be authorized to access the content within the DLC. Authorization can only happen once a player has been Authenticated.

Accounts are where you store various pieces of metadata about a player long-term. Depending on the game, metadata can vary widely. In its most basic form, we provide a player with an account after they have authenticated and may store authorization metadata on the account. In more complex account systems the metadata associated with the account can be rather complex. Basic information such as usernames/gamertags can be associated with it or more complex information such as a player’s inventory can be attached to a player account.

This piece focuses on authentication. It’s difficult to decouple authentication and accounts so we will scrape the surface of accounts as well, though a future piece will dive into the nuances of account systems in more detail.

One of the most important concepts in a live services or multiplayer game is the player account. Player accounts can be tedious to implement and usually have little to no relevance to the actual gameplay of any given game. A good authentication flow and accounts system is never noticed, whereas a bad one can be a massive detriment to your game.

Most players don’t care how they log in, or how you store their information. They only care that they can get in and play the game, their player account is the same everywhere they play, their information is secure, and they won’t ever get locked out. If we as game developers can make authentication appear simple to the player, we’ve done our job. This is easier said than done, as authentication systems contain many minute details that if not done correctly can cause problems for your game. Some questions that come to mind:

  • Do I even need an authentication and accounts system?
  • If so, should I write my own authentication solution?
  • How does a player log in? Do they provide a username and password or do they log in with an external identity provider such as Google, Apple, Steam, Epic, Nintendo, Sony, or Microsoft?
  • If we allow players to log in with external identity providers, how do we handle adding new providers after our game has launched?
  • What are best practices we need to follow when handling player login?
  • How do I continue to identify players once they’ve logged in?

Answering these questions and implementing a well designed authentication and accounts system will lay the foundation for virtually all other backend features that your game will utilize.

Let’s explore some answers to these questions.

Do I Even Need An Authentication And Accounts System?

You may not need an authentication and accounts system depending on the needs of your game. Games like Among Us have seen massive success before adding anything of the sort. You too may be able to get by without an accounts system. The best way to determine if you do or do not need an authentication and accounts system is to ask:

Do I need to uniquely identify players for any reason? When Among Us achieved widespread success in 2020, it did not uniquely identify players in any way. Players could browse lobbies created by others and join them to play games. Players could also create a lobby, receive a lobby code, and share that code with their friends to play with people they knew in real life. Because they did not have any type of progression system, real-time matchmaking, or social features such as friends lists, they could punt on the need for an authentication and accounts solution until they had proven their game was a success. Your game may have different needs and may require the ability to uniquely identify players, but it’s worth asking yourself if it’s absolutely necessary.

Am I shipping my game through a single provider? (Google, Apple, Steam, Epic, Nintendo, Sony, or Microsoft) If you are not planning on shipping your game through multiple providers, you may be able to get away with using that provider’s authentication and accounts system. Some providers offer a variety of additional features for your game backend, such as Steam via Steamworks or Epic via EOS Epic Account Services. We will cover these options in further detail in later posts. If you are planning on distributing your game through multiple channels, relying on a single provider’s authentication and accounts systems will not be sufficient as other backend systems you build on top of that foundation will need to juggle multiple account ID types.

Should I Write My Own Authentication Solution?

If you’ve gotten this far, you’ve determined that you do need an authentication solution. The next question is whether you should build your own or lean on a pre-existing service. This decision comes down to a number of factors, usually flexibility and your desire to use third party vendors. Writing your own solution provides flexibility and extensibility. You own all the code and can change things to suit your needs. At the same time, this is more code you need to maintain. Often, the energy spent on an authentication solution is better spent elsewhere.

There are many pre-existing solutions out there. We will refrain from providing an exhaustive list, but here are a few:

Catena Tools - https://catenatools.com/

Wolfjaw’s own toolset, Catena Tools, provides auth and accounts functionality out of the box. It is meant to be extensible, giving you the same flexibility as if you had written a custom solution, while giving you a jump start to the feature set. As this post is meant to walk you through the nuances of writing your own solution, we won’t dive too deep into utilizing this toolset. If you or your team would like assistance standing Catena up on your infrastructure contact our development team or join our Discord. We’d be happy to help!

Auth0 - https://auth0.com/

Auth0 is one of the most popular providers, serving customers both inside and outside of the games industry. One thing to keep in mind is you will be restricted to a limited list of identity providers your players can use to authenticate. At the time of writing, Auth0 does not support logging in with many game platforms, including Steam, Epic, Nintendo, and Sony. Relying on Auth0 for your game will almost certainly require players to manually provide an email and password which not only is a suboptimal player experience, but will cause your game to fail certification if you are targeting Switch, Playstation, or Xbox. All that being said, if you are interested in learning more about general authentication and authorization concepts, the Auth0 blog is a fantastic resource. FusionAuth - https://fusionauth.io/

FusionAuth is a popular alternative to Auth0, and does provide integrations with identity providers in the gaming industry. One of the largest factors to consider when choosing whether to build your own authentication and accounts system is cost. Many third party vendors that are focused entirely on auth and accounts have a considerable price tag attached to them, especially as your player counts rise. FusionAuth is no exception.

Epic Online Services (EOS) - https://dev.epicgames.com/en-US/services

EOS is a games industry specific toolset that is free to use. If you’d like to build the rest of your backend custom, their connect interface can be used in isolation for authentication and account management. They have the added bonus of providing Kid Web Services (KWS) which can be used in tandem with their auth/accounts offering for handling players that are underage. One constraint of using EOS is they do not provide an off the shelf method to link different identity providers to a single player’s account, rather providing a series of APIs to accomplish that task. If you plan to support cross-progression (allowing a player to log in to their same account on multiple platforms), you will need to write a backend service to sit in between game clients and EOS. We will cover how to implement this in a later post.

Pragma, RallyHere, Nakama, AccelByte, Playfab

There are a variety of other solutions on the market today, that provide auth and accounts functionality. Each of these platforms provides additional features on top of auth and accounts, and each has their own strengths and weaknesses. For the purposes of this post, we will not dive into the nuances of each platform.

Now that we’ve taken a look at some of the off the shelf solutions that are available, let’s dive deeper into what it takes to build out an auth and accounts system on your own.

How Does A Player Log In?

Username and Password

One way to validate a player’s identity is with a username (or email) and password combination, but this comes with some gotchas. You have to worry about security, including password strength, hashing and salting, protecting against brute-force attacks, and multi-factor authentication (MFA). Once you’ve considered all of the security concerns, you also need to provide methods for account recovery which means you will need the ability to send player’s emails or SMS messages. There are many different ways to address each of these factors. We are only going to scrape the surface for each today, but the important thing is you are’re thinking of each when implementing your own username and password based system.

Password Strength

If you are implementing authentication using username and password, you will need to ensure that passwords are sufficiently strong. This can be done by enforcing a level of complexity in passwords that may include their length or variety of characters (uppercase vs. lowercase, numbers, and special characters). You may also want to consider disallowing certain passwords from being used that are commonly used and easily guessed. For example, you may choose to prevent players from using a password that is “password123”.

Hashing

When storing passwords in a database, you do not want them to be stored in plain-text. Instead, passwords should be hashed which prevents anybody who has access to the database from obtaining a player’s password. Hashing is the process of converting a plain-text password into a fixed-sized string of characters. It is non-reversible, meaning that once you have hashed a password you cannot use the result to determine what the original password was. Common hashing algorithms include SHA-256 and bcrypt. Other hashing algorithms such as MD5 are considered to be outdated for password hashing as they are relatively easy to crack.

Salting

Salting is the process of appending/prepending a random string of characters, or a salt, to a player’s password before hashing it upon account creation. This ensures that players with identical passwords end up with different password hashes. You typically will store both the player’s salt and password hash on their player account, using the salt and provided password to generate a hash and checking it is equivalent to what is stored in the database every time a player attempts to log in.

Protecting Against Brute-Force Attacks

By hashing and salting your passwords, you are already taking steps to prevent brute-force attacks, though additional steps can be taken. One method is to store an integer that tracks login attempts on a player’s account. If a certain threshold of attempts has been reached, we can set a datetime value on the player’s account some number of minutes in the future in which any subsequent attempts will be rejected until that time. Just remember to reset that datetime value and the number of attempts on the first subsequent attempt after the time has passed. Another method we can use to prevent brute-force attacks is to rate limit requests via their IP address. We won’t dive deep into the nuances of rate-limiting in this post, but the important thing is you know that it is a tool you have at your disposal.

Multi-Factor Authentication (MFA)

MFA is an additional security measure that requires a player to provide an additional authentication layer to prove their identity. There are many methods to implement MFA, but for the purposes of this post we’ll focus on a specific type of MFA, called Two-Factor Authentication (2FA). You’ve likely experienced 2FA as a user at some point in your life. The most common implementation is via text messaging, where after a user/player logs in with their username or password, they receive a text message with a 2FA code that must be entered to the system they are trying to access. MFA provides an additional layer of security on top of usernames and passwords, ensuring accounts that have their credentials compromised remain secure.

Account Recovery

After you’ve addressed all the security concerns to keep bad actors out of your player’s accounts, you need to provide tooling to let your players into their accounts in the event they get locked out. There are a variety of ways to accomplish this, two of which are email and SMS. This typically requires you to capture a method of contact during account registration and implement a verification flow to ensure players actually have access to that method. After this, if they have’ve forgotten their password you can implement a flow that sends them a temporary access code via their method of contact, prompts on-screen for that code, and then allows for them to change their password.

Basic Username and Password Data Sequence Diagram - Create Account

Basic Username and Password Data Sequence Diagram - Login

All in all, username and password are an effective way to handle authentication in a custom built system. One thing we have not talked about is the player experience though, which at Wolfjaw we hold paramount. Much like above when we talked about Auth0, username and password flows are both suboptimal in regards to player experience, but also will cause your game to fail certification if you are targeting Switch, Playstation, or Xbox. There is a better way…

OAuth 2.0 and OpenID Connect (OIDC)

Enter OAuth 2.0 and OIDC. In a half-joking kind of way, these protocols let you lean on other people to handle authentication for you. Utilizing these protocols, we can allow players to login to our platform using their credentials from other providers. These are the “Login With {Insert Provider Here}” buttons you see across the web, which allow players to sign in with the same credentials everywhere.

OAuth2.0 is the industry-standard protocol for authorization. On its own, OAuth is not sufficient for validating a player’s identity. For more information about why this is the case, you can refer to OAuth’s official User Authentication with OAuth 2.0 article.

OIDC is an identity layer built on top of the OAuth 2.0 framework. It allows third-party applications to verify a player’s identity.

Some identity providers do not implement OIDC, but do provide a method for you to utilize OAuth to authorize your backend platform to access identity information about a player. It’s worth noting that there are a variety of OAuth flows depending on the context you find yourself in. For web-based applications, an Authorization Code Flow is typically used. For games that are shipped on console, a Resource Owner Password Flow is likely happening behind the scenes. In this flow, a player provides a username/password directly to the Identity Provider and is returned an access token directly.

Let’s take a look at how we’d use each flow, depending on what the identity provider’s API interface looks like and the context we find ourselves in.

Web Based - OAuth Authorization Code Flow

You will commonly use this web based flow when building account linking sites, for linking multiple identity providers to a single game account, or for other companion sites.

The main difference between a pure OAuth flow and an OIDC flow is rather than just returning an access token, the Identity Provider Backend will also issue an ID token. This ID token takes the form of a JSON Web Token (JWT). It can be decoded, using its contents to identify a player instead of a subsequent request for player information as outlined above.

Console Based - OAuth Resource Owner Password Flow

When shipping your game on consoles, you will frequently have an access token already available to you via a platform SDK. In this flow, credentials are provided directly to the identity provider through their own interfaces (i.e. signing into your Playstation account via UI’s on the Playstation itself) and access tokens are made available to games running on the platform. The following diagram will outline the typical process to create an account in your system with that token.

It’s worth noting that username/password, and OAuth flows are not mutually exclusive! Your backend could provide multiple methods for a player to authenticate.

How Do I Continue To Identify Players Once They’ve Logged In?

In the above diagrams, we note that upon successfully validating a player’s identity that we should return a token or a session to the game client. Without this, we would need players to provide a username/password or go through an OAuth flow on every request they make to our backend.

There are two very common ways to refer to a player’s session, JSON Web Tokens (JWTs) and Session IDs, which are ephemeral unique identifiers that are stored on the backend to keep track of players that have already logged in. Each approach to identifying players has its pros and cons.

JSON Web Tokens (JWTs)

JWTs are JSON data encoded as a string and cryptographically signed. Within that JSON data are Claims. These Claims often hold a variety of useful pieces of information about the player who generated the JWT in addition to other fields such as the JWT expiration time.

In authentication flows, JWTs are commonly returned to game clients to cache. In subsequent requests to the backend, the game client can provide its cached JWT in an Authorization header. The backend is expected to check this header for every endpoint it wants a player to be authenticated for.

JWTs are nice because they are stateless. The server can validate the token without needing to make any database or network requests, as all of the information needed for validation is embedded in the JWT. Many backends take this a step further by embedded additional custom Claims into a JWT regarding the player’s account or session, reducing load on databases and removing network latency from many calls.

Session Management

Sessions are similar to JWTs in that upon authentication, we return a token to the game client. Where JWTs are stateless, sessions are not. These are typically random strings that do not contain any information about a user. Let’s take a look at extending our earlier console based OAuth flow.

Here, we see how we utilize a cache layer such as Redis or Memcached to store session tokens and check them on subsequent requests.

One of the primary benefits of going this route vs. JWTs is your ability to revoke access to your backend. Once a JWT is issued, it will be valid until it expires. Using sessions, you can instead revoke individual access as needed without needing to wait for an expiry. Cache layers are typically incredibly fast, so the added query time is negligible when compared to decoding a JWT.

Refresh Tokens

Alongside JWTs or traditional sessions, your backend should also return refresh tokens. A refresh token can be used to “refresh” the authentication token that your game client has. This way, instead of needing to re-authenticate every time a session expires, you can instead use the refresh token cached on the client to regenerate a new session. In general, best practice is to provide short lived access tokens alongside longer lived refresh tokens.

Conclusion

We have only scraped the surface of authentication, authorization, and accounts. In future posts we will provide practical examples for building a basic username/password based authentication system, building an OAuth based authentication system, adding multiple identity providers to a system, implementing MFA, implementing rate limiting on your backend, implementing JWT based sessions, and implementing regular sessions. We will additionally be providing more posts like this to give high level overviews of the different components of a game backend.

If you would like to circumvent the need to build an authentication and accounts system from scratch, consider using Catena Tools. If you or your team would like assistance standing Catena up on your infrastructure contact our development team or join our Discord. We’d be happy to help!